zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

decoder.ex (24017B)


      1 defmodule Jason.DecodeError do
      2   @type t :: %__MODULE__{position: integer, data: String.t}
      3 
      4   defexception [:position, :token, :data]
      5 
      6   def message(%{position: position, token: token}) when is_binary(token) do
      7     "unexpected sequence at position #{position}: #{inspect token}"
      8   end
      9   def message(%{position: position, data: data}) when position == byte_size(data) do
     10     "unexpected end of input at position #{position}"
     11   end
     12   def message(%{position: position, data: data}) do
     13     byte = :binary.at(data, position)
     14     str = <<byte>>
     15     if String.printable?(str) do
     16       "unexpected byte at position #{position}: " <>
     17         "#{inspect byte, base: :hex} (#{inspect str})"
     18     else
     19       "unexpected byte at position #{position}: " <>
     20         "#{inspect byte, base: :hex}"
     21     end
     22   end
     23 end
     24 
     25 defmodule Jason.Decoder do
     26   @moduledoc false
     27 
     28   import Bitwise
     29 
     30   alias Jason.{DecodeError, Codegen}
     31 
     32   import Codegen, only: [bytecase: 2, bytecase: 3]
     33   import Record
     34 
     35   @dialyzer :no_improper_lists
     36 
     37   # @compile :native
     38 
     39   # We use integers instead of atoms to take advantage of the jump table
     40   # optimization
     41   @terminate 0
     42   @array     1
     43   @key       2
     44   @object    3
     45 
     46   defrecordp :decode, [keys: nil, strings: nil, objects: nil, floats: nil]
     47 
     48   def parse(data, opts) when is_binary(data) do
     49     key_decode = key_decode_function(opts)
     50     string_decode = string_decode_function(opts)
     51     float_decode = float_decode_function(opts)
     52     object_decode = object_decode_function(opts)
     53     decode = decode(keys: key_decode, strings: string_decode, objects: object_decode, floats: float_decode)
     54     try do
     55       value(data, data, 0, [@terminate], decode)
     56     catch
     57       {:position, position} ->
     58         {:error, %DecodeError{position: position, data: data}}
     59       {:token, token, position} ->
     60         {:error, %DecodeError{token: token, position: position, data: data}}
     61     else
     62       value ->
     63         {:ok, value}
     64     end
     65   end
     66 
     67   defp key_decode_function(%{keys: :atoms}), do: &String.to_atom/1
     68   defp key_decode_function(%{keys: :atoms!}), do: &String.to_existing_atom/1
     69   defp key_decode_function(%{keys: :strings}), do: &(&1)
     70   defp key_decode_function(%{keys: fun}) when is_function(fun, 1), do: fun
     71 
     72   defp string_decode_function(%{strings: :copy}), do: &:binary.copy/1
     73   defp string_decode_function(%{strings: :reference}), do: &(&1)
     74 
     75   defp object_decode_function(%{objects: :maps}), do: &:maps.from_list/1
     76   defp object_decode_function(%{objects: :ordered_objects}), do: &Jason.OrderedObject.new(:lists.reverse(&1))
     77 
     78   defp float_decode_function(%{floats: :native}) do
     79     fn string, token, skip ->
     80       try do
     81         :erlang.binary_to_float(string)
     82       catch
     83         :error, :badarg ->
     84           token_error(token, skip)
     85       end
     86     end
     87   end
     88 
     89   defp float_decode_function(%{floats: :decimals}) do
     90     fn string, token, skip ->
     91       # silence xref warning
     92       decimal = Decimal
     93       try do
     94         decimal.new(string)
     95       rescue
     96         Decimal.Error ->
     97           token_error(token, skip)
     98       end
     99     end
    100   end
    101 
    102   defp value(data, original, skip, stack, decode) do
    103     bytecase data do
    104       _ in '\s\n\t\r', rest ->
    105         value(rest, original, skip + 1, stack, decode)
    106       _ in '0', rest ->
    107         number_zero(rest, original, skip, stack, decode, 1)
    108       _ in '123456789', rest ->
    109         number(rest, original, skip, stack, decode, 1)
    110       _ in '-', rest ->
    111         number_minus(rest, original, skip, stack, decode)
    112       _ in '"', rest ->
    113         string(rest, original, skip + 1, stack, decode, 0)
    114       _ in '[', rest ->
    115         array(rest, original, skip + 1, stack, decode)
    116       _ in '{', rest ->
    117         object(rest, original, skip + 1, stack, decode)
    118       _ in ']', rest ->
    119         empty_array(rest, original, skip + 1, stack, decode)
    120       _ in 't', rest ->
    121         case rest do
    122           <<"rue", rest::bits>> ->
    123             continue(rest, original, skip + 4, stack, decode, true)
    124           <<_::bits>> ->
    125             error(original, skip)
    126         end
    127       _ in 'f', rest ->
    128         case rest do
    129           <<"alse", rest::bits>> ->
    130             continue(rest, original, skip + 5, stack, decode, false)
    131           <<_::bits>> ->
    132             error(original, skip)
    133         end
    134       _ in 'n', rest ->
    135         case rest do
    136           <<"ull", rest::bits>> ->
    137             continue(rest, original, skip + 4, stack, decode, nil)
    138           <<_::bits>> ->
    139             error(original, skip)
    140         end
    141       _, rest ->
    142         error(rest, original, skip + 1, stack, decode)
    143       <<_::bits>> ->
    144         error(original, skip)
    145     end
    146   end
    147 
    148   defp number_minus(<<?0, rest::bits>>, original, skip, stack, decode) do
    149     number_zero(rest, original, skip, stack, decode, 2)
    150   end
    151   defp number_minus(<<byte, rest::bits>>, original, skip, stack, decode)
    152        when byte in '123456789' do
    153     number(rest, original, skip, stack, decode, 2)
    154   end
    155   defp number_minus(<<_rest::bits>>, original, skip, _stack, _decode) do
    156     error(original, skip + 1)
    157   end
    158 
    159   defp number(<<byte, rest::bits>>, original, skip, stack, decode, len)
    160        when byte in '0123456789' do
    161     number(rest, original, skip, stack, decode, len + 1)
    162   end
    163   defp number(<<?., rest::bits>>, original, skip, stack, decode, len) do
    164     number_frac(rest, original, skip, stack, decode, len + 1)
    165   end
    166   defp number(<<e, rest::bits>>, original, skip, stack, decode, len) when e in 'eE' do
    167     prefix = binary_part(original, skip, len)
    168     number_exp_copy(rest, original, skip + len + 1, stack, decode, prefix)
    169   end
    170   defp number(<<rest::bits>>, original, skip, stack, decode, len) do
    171     int = String.to_integer(binary_part(original, skip, len))
    172     continue(rest, original, skip + len, stack, decode, int)
    173   end
    174 
    175   defp number_frac(<<byte, rest::bits>>, original, skip, stack, decode, len)
    176        when byte in '0123456789' do
    177     number_frac_cont(rest, original, skip, stack, decode, len + 1)
    178   end
    179   defp number_frac(<<_rest::bits>>, original, skip, _stack, _decode, len) do
    180     error(original, skip + len)
    181   end
    182 
    183   defp number_frac_cont(<<byte, rest::bits>>, original, skip, stack, decode, len)
    184        when byte in '0123456789' do
    185     number_frac_cont(rest, original, skip, stack, decode, len + 1)
    186   end
    187   defp number_frac_cont(<<e, rest::bits>>, original, skip, stack, decode, len)
    188        when e in 'eE' do
    189     number_exp(rest, original, skip, stack, decode, len + 1)
    190   end
    191   defp number_frac_cont(<<rest::bits>>, original, skip, stack, decode, len) do
    192     token = binary_part(original, skip, len)
    193     decode(floats: float_decode) = decode
    194     float = float_decode.(token, token, skip)
    195     continue(rest, original, skip + len, stack, decode, float)
    196   end
    197 
    198   defp number_exp(<<byte, rest::bits>>, original, skip, stack, decode, len)
    199        when byte in '0123456789' do
    200     number_exp_cont(rest, original, skip, stack, decode, len + 1)
    201   end
    202   defp number_exp(<<byte, rest::bits>>, original, skip, stack, decode, len)
    203        when byte in '+-' do
    204     number_exp_sign(rest, original, skip, stack, decode, len + 1)
    205   end
    206   defp number_exp(<<_rest::bits>>, original, skip, _stack, _decode, len) do
    207     error(original, skip + len)
    208   end
    209 
    210   defp number_exp_sign(<<byte, rest::bits>>, original, skip, stack, decode, len)
    211        when byte in '0123456789' do
    212     number_exp_cont(rest, original, skip, stack, decode, len + 1)
    213   end
    214   defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _decode, len) do
    215     error(original, skip + len)
    216   end
    217 
    218   defp number_exp_cont(<<byte, rest::bits>>, original, skip, stack, decode, len)
    219        when byte in '0123456789' do
    220     number_exp_cont(rest, original, skip, stack, decode, len + 1)
    221   end
    222   defp number_exp_cont(<<rest::bits>>, original, skip, stack, decode, len) do
    223     token = binary_part(original, skip, len)
    224     decode(floats: float_decode) = decode
    225     float = float_decode.(token, token, skip)
    226     continue(rest, original, skip + len, stack, decode, float)
    227   end
    228 
    229   defp number_exp_copy(<<byte, rest::bits>>, original, skip, stack, decode, prefix)
    230        when byte in '0123456789' do
    231     number_exp_cont(rest, original, skip, stack, decode, prefix, 1)
    232   end
    233   defp number_exp_copy(<<byte, rest::bits>>, original, skip, stack, decode, prefix)
    234        when byte in '+-' do
    235     number_exp_sign(rest, original, skip, stack, decode, prefix, 1)
    236   end
    237   defp number_exp_copy(<<_rest::bits>>, original, skip, _stack, _decode, _prefix) do
    238     error(original, skip)
    239   end
    240 
    241   defp number_exp_sign(<<byte, rest::bits>>, original, skip, stack, decode, prefix, len)
    242        when byte in '0123456789' do
    243     number_exp_cont(rest, original, skip, stack, decode, prefix, len + 1)
    244   end
    245   defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _decode, _prefix, len) do
    246     error(original, skip + len)
    247   end
    248 
    249   defp number_exp_cont(<<byte, rest::bits>>, original, skip, stack, decode, prefix, len)
    250        when byte in '0123456789' do
    251     number_exp_cont(rest, original, skip, stack, decode, prefix, len + 1)
    252   end
    253   defp number_exp_cont(<<rest::bits>>, original, skip, stack, decode, prefix, len) do
    254     suffix = binary_part(original, skip, len)
    255     string = prefix <> ".0e" <> suffix
    256     prefix_size = byte_size(prefix)
    257     initial_skip = skip - prefix_size - 1
    258     final_skip = skip + len
    259     token = binary_part(original, initial_skip, prefix_size + len + 1)
    260     decode(floats: float_decode) = decode
    261     float = float_decode.(string, token, initial_skip)
    262     continue(rest, original, final_skip, stack, decode, float)
    263   end
    264 
    265   defp number_zero(<<?., rest::bits>>, original, skip, stack, decode, len) do
    266     number_frac(rest, original, skip, stack, decode, len + 1)
    267   end
    268   defp number_zero(<<e, rest::bits>>, original, skip, stack, decode, len) when e in 'eE' do
    269     number_exp_copy(rest, original, skip + len + 1, stack, decode, "0")
    270   end
    271   defp number_zero(<<rest::bits>>, original, skip, stack, decode, len) do
    272     continue(rest, original, skip + len, stack, decode, 0)
    273   end
    274 
    275   @compile {:inline, array: 5}
    276 
    277   defp array(rest, original, skip, stack, decode) do
    278     value(rest, original, skip, [@array, [] | stack], decode)
    279   end
    280 
    281   defp empty_array(<<rest::bits>>, original, skip, stack, decode) do
    282     case stack do
    283       [@array, [] | stack] ->
    284         continue(rest, original, skip, stack, decode, [])
    285       _ ->
    286         error(original, skip - 1)
    287     end
    288   end
    289 
    290   defp array(data, original, skip, stack, decode, value) do
    291     bytecase data do
    292       _ in '\s\n\t\r', rest ->
    293         array(rest, original, skip + 1, stack, decode, value)
    294       _ in ']', rest ->
    295         [acc | stack] = stack
    296         value = :lists.reverse(acc, [value])
    297         continue(rest, original, skip + 1, stack, decode, value)
    298       _ in ',', rest ->
    299         [acc | stack] = stack
    300         value(rest, original, skip + 1, [@array, [value | acc] | stack], decode)
    301       _, _rest ->
    302         error(original, skip)
    303       <<_::bits>> ->
    304         empty_error(original, skip)
    305     end
    306   end
    307 
    308   @compile {:inline, object: 5}
    309 
    310   defp object(rest, original, skip, stack, decode) do
    311     key(rest, original, skip, [[] | stack], decode)
    312   end
    313 
    314   defp object(data, original, skip, stack, decode, value) do
    315     bytecase data do
    316       _ in '\s\n\t\r', rest ->
    317         object(rest, original, skip + 1, stack, decode, value)
    318       _ in '}', rest ->
    319         skip = skip + 1
    320         [key, acc | stack] = stack
    321         decode(keys: key_decode) = decode
    322         final = [{key_decode.(key), value} | acc]
    323         decode(objects: object_decode) = decode
    324         continue(rest, original, skip, stack, decode, object_decode.(final))
    325       _ in ',', rest ->
    326         skip = skip + 1
    327         [key, acc | stack] = stack
    328         decode(keys: key_decode) = decode
    329         acc = [{key_decode.(key), value} | acc]
    330         key(rest, original, skip, [acc | stack], decode)
    331       _, _rest ->
    332         error(original, skip)
    333       <<_::bits>> ->
    334         empty_error(original, skip)
    335     end
    336   end
    337 
    338   defp key(data, original, skip, stack, decode) do
    339     bytecase data do
    340       _ in '\s\n\t\r', rest ->
    341         key(rest, original, skip + 1, stack, decode)
    342       _ in '}', rest ->
    343         case stack do
    344           [[] | stack] ->
    345             decode(objects: object_decode) = decode
    346             continue(rest, original, skip + 1, stack, decode, object_decode.([]))
    347           _ ->
    348             error(original, skip)
    349         end
    350       _ in '"', rest ->
    351         string(rest, original, skip + 1, [@key | stack], decode, 0)
    352       _, _rest ->
    353         error(original, skip)
    354       <<_::bits>> ->
    355         empty_error(original, skip)
    356     end
    357   end
    358 
    359   defp key(data, original, skip, stack, decode, value) do
    360     bytecase data do
    361       _ in '\s\n\t\r', rest ->
    362         key(rest, original, skip + 1, stack, decode, value)
    363       _ in ':', rest ->
    364         value(rest, original, skip + 1, [@object, value | stack], decode)
    365       _, _rest ->
    366         error(original, skip)
    367       <<_::bits>> ->
    368         empty_error(original, skip)
    369     end
    370   end
    371 
    372   # TODO: check if this approach would be faster:
    373   # https://git.ninenines.eu/cowlib.git/tree/src/cow_ws.erl#n469
    374   # http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
    375   defp string(data, original, skip, stack, decode, len) do
    376     bytecase data, 128 do
    377       _ in '"', rest ->
    378         decode(strings: string_decode) = decode
    379         string = string_decode.(binary_part(original, skip, len))
    380         continue(rest, original, skip + len + 1, stack, decode, string)
    381       _ in '\\', rest ->
    382         part = binary_part(original, skip, len)
    383         escape(rest, original, skip + len, stack, decode, part)
    384       _ in unquote(0x00..0x1F), _rest ->
    385         error(original, skip + len)
    386       _, rest ->
    387         string(rest, original, skip, stack, decode, len + 1)
    388       <<char::utf8, rest::bits>> when char <= 0x7FF ->
    389         string(rest, original, skip, stack, decode, len + 2)
    390       <<char::utf8, rest::bits>> when char <= 0xFFFF ->
    391         string(rest, original, skip, stack, decode, len + 3)
    392       <<_char::utf8, rest::bits>> ->
    393         string(rest, original, skip, stack, decode, len + 4)
    394       <<_::bits>> ->
    395         empty_error(original, skip + len)
    396     end
    397   end
    398 
    399   defp string(data, original, skip, stack, decode, acc, len) do
    400     bytecase data, 128 do
    401       _ in '"', rest ->
    402         last = binary_part(original, skip, len)
    403         string = IO.iodata_to_binary([acc | last])
    404         continue(rest, original, skip + len + 1, stack, decode, string)
    405       _ in '\\', rest ->
    406         part = binary_part(original, skip, len)
    407         escape(rest, original, skip + len, stack, decode, [acc | part])
    408       _ in unquote(0x00..0x1F), _rest ->
    409         error(original, skip + len)
    410       _, rest ->
    411         string(rest, original, skip, stack, decode, acc, len + 1)
    412       <<char::utf8, rest::bits>> when char <= 0x7FF ->
    413         string(rest, original, skip, stack, decode, acc, len + 2)
    414       <<char::utf8, rest::bits>> when char <= 0xFFFF ->
    415         string(rest, original, skip, stack, decode, acc, len + 3)
    416       <<_char::utf8, rest::bits>> ->
    417         string(rest, original, skip, stack, decode, acc, len + 4)
    418       <<_::bits>> ->
    419         empty_error(original, skip + len)
    420     end
    421   end
    422 
    423   defp escape(data, original, skip, stack, decode, acc) do
    424     bytecase data do
    425       _ in 'b', rest ->
    426         string(rest, original, skip + 2, stack, decode, [acc | '\b'], 0)
    427       _ in 't', rest ->
    428         string(rest, original, skip + 2, stack, decode, [acc | '\t'], 0)
    429       _ in 'n', rest ->
    430         string(rest, original, skip + 2, stack, decode, [acc | '\n'], 0)
    431       _ in 'f', rest ->
    432         string(rest, original, skip + 2, stack, decode, [acc | '\f'], 0)
    433       _ in 'r', rest ->
    434         string(rest, original, skip + 2, stack, decode, [acc | '\r'], 0)
    435       _ in '"', rest ->
    436         string(rest, original, skip + 2, stack, decode, [acc | '\"'], 0)
    437       _ in '/', rest ->
    438         string(rest, original, skip + 2, stack, decode, [acc | '/'], 0)
    439       _ in '\\', rest ->
    440         string(rest, original, skip + 2, stack, decode, [acc | '\\'], 0)
    441       _ in 'u', rest ->
    442         escapeu(rest, original, skip, stack, decode, acc)
    443       _, _rest ->
    444         error(original, skip + 1)
    445       <<_::bits>> ->
    446         empty_error(original, skip)
    447     end
    448   end
    449 
    450   defmodule Unescape do
    451     @moduledoc false
    452 
    453     import Bitwise
    454 
    455     @digits Enum.concat([?0..?9, ?A..?F, ?a..?f])
    456 
    457     def unicode_escapes(chars1 \\ @digits, chars2 \\ @digits) do
    458       for char1 <- chars1, char2 <- chars2 do
    459         {(char1 <<< 8) + char2, integer8(char1, char2)}
    460       end
    461     end
    462 
    463     defp integer8(char1, char2) do
    464       (integer4(char1) <<< 4) + integer4(char2)
    465     end
    466 
    467     defp integer4(char) when char in ?0..?9, do: char - ?0
    468     defp integer4(char) when char in ?A..?F, do: char - ?A + 10
    469     defp integer4(char) when char in ?a..?f, do: char - ?a + 10
    470 
    471     defp token_error_clause(original, skip, len) do
    472       quote do
    473         _ ->
    474           token_error(unquote_splicing([original, skip, len]))
    475       end
    476     end
    477 
    478     defmacro escapeu_first(int, last, rest, original, skip, stack, decode, acc) do
    479       clauses = escapeu_first_clauses(last, rest, original, skip, stack, decode, acc)
    480       quote location: :keep do
    481         case unquote(int) do
    482           unquote(clauses ++ token_error_clause(original, skip, 6))
    483         end
    484       end
    485     end
    486 
    487     defp escapeu_first_clauses(last, rest, original, skip, stack, decode, acc) do
    488       for {int, first} <- unicode_escapes(),
    489           not (first in 0xDC..0xDF) do
    490         escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc)
    491       end
    492     end
    493 
    494     defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc)
    495          when first in 0xD8..0xDB do
    496       hi =
    497         quote bind_quoted: [first: first, last: last] do
    498           0x10000 + ((((first &&& 0x03) <<< 8) + last) <<< 10)
    499         end
    500       args = [rest, original, skip, stack, decode, acc, hi]
    501       [clause] =
    502         quote location: :keep do
    503           unquote(int) -> escape_surrogate(unquote_splicing(args))
    504         end
    505       clause
    506     end
    507 
    508     defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc)
    509          when first <= 0x00 do
    510       skip = quote do: (unquote(skip) + 6)
    511       acc =
    512         quote bind_quoted: [acc: acc, first: first, last: last] do
    513           if last <= 0x7F do
    514             # 0?????
    515             [acc, last]
    516           else
    517             # 110xxxx??  10?????
    518             byte1 = ((0b110 <<< 5) + (first <<< 2)) + (last >>> 6)
    519             byte2 = (0b10 <<< 6) + (last &&& 0b111111)
    520             [acc, byte1, byte2]
    521           end
    522         end
    523       args = [rest, original, skip, stack, decode, acc, 0]
    524       [clause] =
    525         quote location: :keep do
    526           unquote(int) -> string(unquote_splicing(args))
    527         end
    528       clause
    529     end
    530 
    531     defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc)
    532          when first <= 0x07 do
    533       skip = quote do: (unquote(skip) + 6)
    534       acc =
    535         quote bind_quoted: [acc: acc, first: first, last: last] do
    536           # 110xxx??  10??????
    537           byte1 = ((0b110 <<< 5) + (first <<< 2)) + (last >>> 6)
    538           byte2 = (0b10 <<< 6) + (last &&& 0b111111)
    539           [acc, byte1, byte2]
    540         end
    541       args = [rest, original, skip, stack, decode, acc, 0]
    542       [clause] =
    543         quote location: :keep do
    544           unquote(int) -> string(unquote_splicing(args))
    545         end
    546       clause
    547     end
    548 
    549     defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc)
    550          when first <= 0xFF do
    551       skip = quote do: (unquote(skip) + 6)
    552       acc =
    553         quote bind_quoted: [acc: acc, first: first, last: last] do
    554           # 1110xxxx  10xxxx??  10??????
    555           byte1 = (0b1110 <<< 4) + (first >>> 4)
    556           byte2 = ((0b10 <<< 6) + ((first &&& 0b1111) <<< 2)) + (last >>> 6)
    557           byte3 = (0b10 <<< 6) + (last &&& 0b111111)
    558           [acc, byte1, byte2, byte3]
    559         end
    560       args = [rest, original, skip, stack, decode, acc, 0]
    561       [clause] =
    562         quote location: :keep do
    563           unquote(int) -> string(unquote_splicing(args))
    564         end
    565       clause
    566     end
    567 
    568     defmacro escapeu_last(int, original, skip) do
    569       clauses = escapeu_last_clauses()
    570       quote location: :keep do
    571         case unquote(int) do
    572           unquote(clauses ++ token_error_clause(original, skip, 6))
    573         end
    574       end
    575     end
    576 
    577     defp escapeu_last_clauses() do
    578       for {int, last} <- unicode_escapes() do
    579         [clause] =
    580           quote do
    581             unquote(int) -> unquote(last)
    582           end
    583         clause
    584       end
    585     end
    586 
    587     defmacro escapeu_surrogate(int, last, rest, original, skip, stack, decode, acc,
    588              hi) do
    589       clauses = escapeu_surrogate_clauses(last, rest, original, skip, stack, decode, acc, hi)
    590       quote location: :keep do
    591         case unquote(int) do
    592           unquote(clauses ++ token_error_clause(original, skip, 12))
    593         end
    594       end
    595     end
    596 
    597     defp escapeu_surrogate_clauses(last, rest, original, skip, stack, decode, acc, hi) do
    598       digits1 = 'Dd'
    599       digits2 = Stream.concat([?C..?F, ?c..?f])
    600       for {int, first} <- unicode_escapes(digits1, digits2) do
    601         escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, decode, acc, hi)
    602       end
    603     end
    604 
    605     defp escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, decode, acc, hi) do
    606       skip = quote do: unquote(skip) + 12
    607       acc =
    608         quote bind_quoted: [acc: acc, first: first, last: last, hi: hi] do
    609           lo = ((first &&& 0x03) <<< 8) + last
    610           [acc | <<(hi + lo)::utf8>>]
    611         end
    612       args = [rest, original, skip, stack, decode, acc, 0]
    613       [clause] =
    614         quote do
    615           unquote(int) ->
    616             string(unquote_splicing(args))
    617         end
    618       clause
    619     end
    620   end
    621 
    622   defp escapeu(<<int1::16, int2::16, rest::bits>>, original, skip, stack, decode, acc) do
    623     require Unescape
    624     last = escapeu_last(int2, original, skip)
    625     Unescape.escapeu_first(int1, last, rest, original, skip, stack, decode, acc)
    626   end
    627   defp escapeu(<<_rest::bits>>, original, skip, _stack, _decode, _acc) do
    628     empty_error(original, skip)
    629   end
    630 
    631   # @compile {:inline, escapeu_last: 3}
    632 
    633   defp escapeu_last(int, original, skip) do
    634     require Unescape
    635     Unescape.escapeu_last(int, original, skip)
    636   end
    637 
    638   defp escape_surrogate(<<?\\, ?u, int1::16, int2::16, rest::bits>>, original,
    639        skip, stack, decode, acc, hi) do
    640     require Unescape
    641     last = escapeu_last(int2, original, skip + 6)
    642     Unescape.escapeu_surrogate(int1, last, rest, original, skip, stack, decode, acc, hi)
    643   end
    644   defp escape_surrogate(<<_rest::bits>>, original, skip, _stack, _decode, _acc, _hi) do
    645     error(original, skip + 6)
    646   end
    647 
    648   defp error(<<_rest::bits>>, _original, skip, _stack, _decode) do
    649     throw {:position, skip - 1}
    650   end
    651 
    652   defp empty_error(_original, skip) do
    653     throw {:position, skip}
    654   end
    655 
    656   @compile {:inline, error: 2, token_error: 2, token_error: 3}
    657   defp error(_original, skip) do
    658     throw {:position, skip}
    659   end
    660 
    661   defp token_error(token, position) do
    662     throw {:token, token, position}
    663   end
    664 
    665   defp token_error(token, position, len) do
    666     throw {:token, binary_part(token, position, len), position}
    667   end
    668 
    669   @compile {:inline, continue: 6}
    670   defp continue(rest, original, skip, stack, decode, value) do
    671     case stack do
    672       [@terminate | stack] ->
    673         terminate(rest, original, skip, stack, decode, value)
    674       [@array | stack] ->
    675         array(rest, original, skip, stack, decode, value)
    676       [@key | stack] ->
    677         key(rest, original, skip, stack, decode, value)
    678       [@object | stack] ->
    679         object(rest, original, skip, stack, decode, value)
    680     end
    681   end
    682 
    683   defp terminate(<<byte, rest::bits>>, original, skip, stack, decode, value)
    684        when byte in '\s\n\r\t' do
    685     terminate(rest, original, skip + 1, stack, decode, value)
    686   end
    687   defp terminate(<<>>, _original, _skip, _stack, _decode, value) do
    688     value
    689   end
    690   defp terminate(<<_rest::bits>>, original, skip, _stack, _decode, _value) do
    691     error(original, skip)
    692   end
    693 end