From 40d9c51a66dcc5b99527c0ef437285ccb3baf6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Muska=C5=82a?= Date: Tue, 21 Dec 2021 12:51:12 +0100 Subject: [PATCH] Abstract over decoders in Jason.Decode This will allow to easily implement extensions like decimal or alternative object decoding. I could not measure meaninful performance impact. --- lib/decoder.ex | 302 +++++++++++++++++++++++++------------------------ 1 file changed, 154 insertions(+), 148 deletions(-) diff --git a/lib/decoder.ex b/lib/decoder.ex index 4f251d1..71c59ed 100644 --- a/lib/decoder.ex +++ b/lib/decoder.ex @@ -30,6 +30,7 @@ defmodule Jason.Decoder do alias Jason.{DecodeError, Codegen} import Codegen, only: [bytecase: 2, bytecase: 3] + import Record @dialyzer :no_improper_lists @@ -42,11 +43,13 @@ defmodule Jason.Decoder do @key 2 @object 3 + defrecordp :decode, [keys: nil, strings: nil] + def parse(data, opts) when is_binary(data) do key_decode = key_decode_function(opts) string_decode = string_decode_function(opts) try do - value(data, data, 0, [@terminate], key_decode, string_decode) + value(data, data, 0, [@terminate], decode(keys: key_decode, strings: string_decode)) catch {:position, position} -> {:error, %DecodeError{position: position, data: data}} @@ -66,156 +69,156 @@ defmodule Jason.Decoder do defp string_decode_function(%{strings: :copy}), do: &:binary.copy/1 defp string_decode_function(%{strings: :reference}), do: &(&1) - defp value(data, original, skip, stack, key_decode, string_decode) do + defp value(data, original, skip, stack, decode) do bytecase data do _ in '\s\n\t\r', rest -> - value(rest, original, skip + 1, stack, key_decode, string_decode) + value(rest, original, skip + 1, stack, decode) _ in '0', rest -> - number_zero(rest, original, skip, stack, key_decode, string_decode, 1) + number_zero(rest, original, skip, stack, decode, 1) _ in '123456789', rest -> - number(rest, original, skip, stack, key_decode, string_decode, 1) + number(rest, original, skip, stack, decode, 1) _ in '-', rest -> - number_minus(rest, original, skip, stack, key_decode, string_decode) + number_minus(rest, original, skip, stack, decode) _ in '"', rest -> - string(rest, original, skip + 1, stack, key_decode, string_decode, 0) + string(rest, original, skip + 1, stack, decode, 0) _ in '[', rest -> - array(rest, original, skip + 1, stack, key_decode, string_decode) + array(rest, original, skip + 1, stack, decode) _ in '{', rest -> - object(rest, original, skip + 1, stack, key_decode, string_decode) + object(rest, original, skip + 1, stack, decode) _ in ']', rest -> - empty_array(rest, original, skip + 1, stack, key_decode, string_decode) + empty_array(rest, original, skip + 1, stack, decode) _ in 't', rest -> case rest do <<"rue", rest::bits>> -> - continue(rest, original, skip + 4, stack, key_decode, string_decode, true) + continue(rest, original, skip + 4, stack, decode, true) <<_::bits>> -> error(original, skip) end _ in 'f', rest -> case rest do <<"alse", rest::bits>> -> - continue(rest, original, skip + 5, stack, key_decode, string_decode, false) + continue(rest, original, skip + 5, stack, decode, false) <<_::bits>> -> error(original, skip) end _ in 'n', rest -> case rest do <<"ull", rest::bits>> -> - continue(rest, original, skip + 4, stack, key_decode, string_decode, nil) + continue(rest, original, skip + 4, stack, decode, nil) <<_::bits>> -> error(original, skip) end _, rest -> - error(rest, original, skip + 1, stack, key_decode, string_decode) + error(rest, original, skip + 1, stack, decode) <<_::bits>> -> error(original, skip) end end - defp number_minus(<>, original, skip, stack, key_decode, string_decode) do - number_zero(rest, original, skip, stack, key_decode, string_decode, 2) + defp number_minus(<>, original, skip, stack, decode) do + number_zero(rest, original, skip, stack, decode, 2) end - defp number_minus(<>, original, skip, stack, key_decode, string_decode) + defp number_minus(<>, original, skip, stack, decode) when byte in '123456789' do - number(rest, original, skip, stack, key_decode, string_decode, 2) + number(rest, original, skip, stack, decode, 2) end - defp number_minus(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode) do + defp number_minus(<<_rest::bits>>, original, skip, _stack, _decode) do error(original, skip + 1) end - defp number(<>, original, skip, stack, key_decode, string_decode, len) + defp number(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number(rest, original, skip, stack, key_decode, string_decode, len + 1) + number(rest, original, skip, stack, decode, len + 1) end - defp number(<>, original, skip, stack, key_decode, string_decode, len) do - number_frac(rest, original, skip, stack, key_decode, string_decode, len + 1) + defp number(<>, original, skip, stack, decode, len) do + number_frac(rest, original, skip, stack, decode, len + 1) end - defp number(<>, original, skip, stack, key_decode, string_decode, len) when e in 'eE' do + defp number(<>, original, skip, stack, decode, len) when e in 'eE' do prefix = binary_part(original, skip, len) - number_exp_copy(rest, original, skip + len + 1, stack, key_decode, string_decode, prefix) + number_exp_copy(rest, original, skip + len + 1, stack, decode, prefix) end - defp number(<>, original, skip, stack, key_decode, string_decode, len) do + defp number(<>, original, skip, stack, decode, len) do int = String.to_integer(binary_part(original, skip, len)) - continue(rest, original, skip + len, stack, key_decode, string_decode, int) + continue(rest, original, skip + len, stack, decode, int) end - defp number_frac(<>, original, skip, stack, key_decode, string_decode, len) + defp number_frac(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number_frac_cont(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_frac_cont(rest, original, skip, stack, decode, len + 1) end - defp number_frac(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do + defp number_frac(<<_rest::bits>>, original, skip, _stack, _decode, len) do error(original, skip + len) end - defp number_frac_cont(<>, original, skip, stack, key_decode, string_decode, len) + defp number_frac_cont(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number_frac_cont(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_frac_cont(rest, original, skip, stack, decode, len + 1) end - defp number_frac_cont(<>, original, skip, stack, key_decode, string_decode, len) + defp number_frac_cont(<>, original, skip, stack, decode, len) when e in 'eE' do - number_exp(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_exp(rest, original, skip, stack, decode, len + 1) end - defp number_frac_cont(<>, original, skip, stack, key_decode, string_decode, len) do + defp number_frac_cont(<>, original, skip, stack, decode, len) do token = binary_part(original, skip, len) float = try_parse_float(token, token, skip) - continue(rest, original, skip + len, stack, key_decode, string_decode, float) + continue(rest, original, skip + len, stack, decode, float) end - defp number_exp(<>, original, skip, stack, key_decode, string_decode, len) + defp number_exp(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_exp_cont(rest, original, skip, stack, decode, len + 1) end - defp number_exp(<>, original, skip, stack, key_decode, string_decode, len) + defp number_exp(<>, original, skip, stack, decode, len) when byte in '+-' do - number_exp_sign(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_exp_sign(rest, original, skip, stack, decode, len + 1) end - defp number_exp(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do + defp number_exp(<<_rest::bits>>, original, skip, _stack, _decode, len) do error(original, skip + len) end - defp number_exp_sign(<>, original, skip, stack, key_decode, string_decode, len) + defp number_exp_sign(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_exp_cont(rest, original, skip, stack, decode, len + 1) end - defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do + defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _decode, len) do error(original, skip + len) end - defp number_exp_cont(<>, original, skip, stack, key_decode, string_decode, len) + defp number_exp_cont(<>, original, skip, stack, decode, len) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1) + number_exp_cont(rest, original, skip, stack, decode, len + 1) end - defp number_exp_cont(<>, original, skip, stack, key_decode, string_decode, len) do + defp number_exp_cont(<>, original, skip, stack, decode, len) do token = binary_part(original, skip, len) float = try_parse_float(token, token, skip) - continue(rest, original, skip + len, stack, key_decode, string_decode, float) + continue(rest, original, skip + len, stack, decode, float) end - defp number_exp_copy(<>, original, skip, stack, key_decode, string_decode, prefix) + defp number_exp_copy(<>, original, skip, stack, decode, prefix) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, 1) + number_exp_cont(rest, original, skip, stack, decode, prefix, 1) end - defp number_exp_copy(<>, original, skip, stack, key_decode, string_decode, prefix) + defp number_exp_copy(<>, original, skip, stack, decode, prefix) when byte in '+-' do - number_exp_sign(rest, original, skip, stack, key_decode, string_decode, prefix, 1) + number_exp_sign(rest, original, skip, stack, decode, prefix, 1) end - defp number_exp_copy(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _prefix) do + defp number_exp_copy(<<_rest::bits>>, original, skip, _stack, _decode, _prefix) do error(original, skip) end - defp number_exp_sign(<>, original, skip, stack, key_decode, string_decode, prefix, len) + defp number_exp_sign(<>, original, skip, stack, decode, prefix, len) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, len + 1) + number_exp_cont(rest, original, skip, stack, decode, prefix, len + 1) end - defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _prefix, len) do + defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _decode, _prefix, len) do error(original, skip + len) end - defp number_exp_cont(<>, original, skip, stack, key_decode, string_decode, prefix, len) + defp number_exp_cont(<>, original, skip, stack, decode, prefix, len) when byte in '0123456789' do - number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, len + 1) + number_exp_cont(rest, original, skip, stack, decode, prefix, len + 1) end - defp number_exp_cont(<>, original, skip, stack, key_decode, string_decode, prefix, len) do + defp number_exp_cont(<>, original, skip, stack, decode, prefix, len) do suffix = binary_part(original, skip, len) string = prefix <> ".0e" <> suffix prefix_size = byte_size(prefix) @@ -223,45 +226,45 @@ defmodule Jason.Decoder do final_skip = skip + len token = binary_part(original, initial_skip, prefix_size + len + 1) float = try_parse_float(string, token, initial_skip) - continue(rest, original, final_skip, stack, key_decode, string_decode, float) + continue(rest, original, final_skip, stack, decode, float) end - defp number_zero(<>, original, skip, stack, key_decode, string_decode, len) do - number_frac(rest, original, skip, stack, key_decode, string_decode, len + 1) + defp number_zero(<>, original, skip, stack, decode, len) do + number_frac(rest, original, skip, stack, decode, len + 1) end - defp number_zero(<>, original, skip, stack, key_decode, string_decode, len) when e in 'eE' do - number_exp_copy(rest, original, skip + len + 1, stack, key_decode, string_decode, "0") + defp number_zero(<>, original, skip, stack, decode, len) when e in 'eE' do + number_exp_copy(rest, original, skip + len + 1, stack, decode, "0") end - defp number_zero(<>, original, skip, stack, key_decode, string_decode, len) do - continue(rest, original, skip + len, stack, key_decode, string_decode, 0) + defp number_zero(<>, original, skip, stack, decode, len) do + continue(rest, original, skip + len, stack, decode, 0) end - @compile {:inline, array: 6} + @compile {:inline, array: 5} - defp array(rest, original, skip, stack, key_decode, string_decode) do - value(rest, original, skip, [@array, [] | stack], key_decode, string_decode) + defp array(rest, original, skip, stack, decode) do + value(rest, original, skip, [@array, [] | stack], decode) end - defp empty_array(<>, original, skip, stack, key_decode, string_decode) do + defp empty_array(<>, original, skip, stack, decode) do case stack do [@array, [] | stack] -> - continue(rest, original, skip, stack, key_decode, string_decode, []) + continue(rest, original, skip, stack, decode, []) _ -> error(original, skip - 1) end end - defp array(data, original, skip, stack, key_decode, string_decode, value) do + defp array(data, original, skip, stack, decode, value) do bytecase data do _ in '\s\n\t\r', rest -> - array(rest, original, skip + 1, stack, key_decode, string_decode, value) + array(rest, original, skip + 1, stack, decode, value) _ in ']', rest -> [acc | stack] = stack value = :lists.reverse(acc, [value]) - continue(rest, original, skip + 1, stack, key_decode, string_decode, value) + continue(rest, original, skip + 1, stack, decode, value) _ in ',', rest -> [acc | stack] = stack - value(rest, original, skip + 1, [@array, [value | acc] | stack], key_decode, string_decode) + value(rest, original, skip + 1, [@array, [value | acc] | stack], decode) _, _rest -> error(original, skip) <<_::bits>> -> @@ -269,26 +272,28 @@ defmodule Jason.Decoder do end end - @compile {:inline, object: 6} + @compile {:inline, object: 5} - defp object(rest, original, skip, stack, key_decode, string_decode) do - key(rest, original, skip, [[] | stack], key_decode, string_decode) + defp object(rest, original, skip, stack, decode) do + key(rest, original, skip, [[] | stack], decode) end - defp object(data, original, skip, stack, key_decode, string_decode, value) do + defp object(data, original, skip, stack, decode, value) do bytecase data do _ in '\s\n\t\r', rest -> - object(rest, original, skip + 1, stack, key_decode, string_decode, value) + object(rest, original, skip + 1, stack, decode, value) _ in '}', rest -> skip = skip + 1 [key, acc | stack] = stack + decode(keys: key_decode) = decode final = [{key_decode.(key), value} | acc] - continue(rest, original, skip, stack, key_decode, string_decode, :maps.from_list(final)) + continue(rest, original, skip, stack, decode, :maps.from_list(final)) _ in ',', rest -> skip = skip + 1 [key, acc | stack] = stack + decode(keys: key_decode) = decode acc = [{key_decode.(key), value} | acc] - key(rest, original, skip, [acc | stack], key_decode, string_decode) + key(rest, original, skip, [acc | stack], decode) _, _rest -> error(original, skip) <<_::bits>> -> @@ -296,19 +301,19 @@ defmodule Jason.Decoder do end end - defp key(data, original, skip, stack, key_decode, string_decode) do + defp key(data, original, skip, stack, decode) do bytecase data do _ in '\s\n\t\r', rest -> - key(rest, original, skip + 1, stack, key_decode, string_decode) + key(rest, original, skip + 1, stack, decode) _ in '}', rest -> case stack do [[] | stack] -> - continue(rest, original, skip + 1, stack, key_decode, string_decode, %{}) + continue(rest, original, skip + 1, stack, decode, %{}) _ -> error(original, skip) end _ in '"', rest -> - string(rest, original, skip + 1, [@key | stack], key_decode, string_decode, 0) + string(rest, original, skip + 1, [@key | stack], decode, 0) _, _rest -> error(original, skip) <<_::bits>> -> @@ -316,12 +321,12 @@ defmodule Jason.Decoder do end end - defp key(data, original, skip, stack, key_decode, string_decode, value) do + defp key(data, original, skip, stack, decode, value) do bytecase data do _ in '\s\n\t\r', rest -> - key(rest, original, skip + 1, stack, key_decode, string_decode, value) + key(rest, original, skip + 1, stack, decode, value) _ in ':', rest -> - value(rest, original, skip + 1, [@object, value | stack], key_decode, string_decode) + value(rest, original, skip + 1, [@object, value | stack], decode) _, _rest -> error(original, skip) <<_::bits>> -> @@ -332,73 +337,74 @@ defmodule Jason.Decoder do # TODO: check if this approach would be faster: # https://git.ninenines.eu/cowlib.git/tree/src/cow_ws.erl#n469 # http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - defp string(data, original, skip, stack, key_decode, string_decode, len) do + defp string(data, original, skip, stack, decode, len) do bytecase data, 128 do _ in '"', rest -> + decode(strings: string_decode) = decode string = string_decode.(binary_part(original, skip, len)) - continue(rest, original, skip + len + 1, stack, key_decode, string_decode, string) + continue(rest, original, skip + len + 1, stack, decode, string) _ in '\\', rest -> part = binary_part(original, skip, len) - escape(rest, original, skip + len, stack, key_decode, string_decode, part) + escape(rest, original, skip + len, stack, decode, part) _ in unquote(0x00..0x1F), _rest -> error(original, skip + len) _, rest -> - string(rest, original, skip, stack, key_decode, string_decode, len + 1) + string(rest, original, skip, stack, decode, len + 1) <> when char <= 0x7FF -> - string(rest, original, skip, stack, key_decode, string_decode, len + 2) + string(rest, original, skip, stack, decode, len + 2) <> when char <= 0xFFFF -> - string(rest, original, skip, stack, key_decode, string_decode, len + 3) + string(rest, original, skip, stack, decode, len + 3) <<_char::utf8, rest::bits>> -> - string(rest, original, skip, stack, key_decode, string_decode, len + 4) + string(rest, original, skip, stack, decode, len + 4) <<_::bits>> -> empty_error(original, skip + len) end end - defp string(data, original, skip, stack, key_decode, string_decode, acc, len) do + defp string(data, original, skip, stack, decode, acc, len) do bytecase data, 128 do _ in '"', rest -> last = binary_part(original, skip, len) string = IO.iodata_to_binary([acc | last]) - continue(rest, original, skip + len + 1, stack, key_decode, string_decode, string) + continue(rest, original, skip + len + 1, stack, decode, string) _ in '\\', rest -> part = binary_part(original, skip, len) - escape(rest, original, skip + len, stack, key_decode, string_decode, [acc | part]) + escape(rest, original, skip + len, stack, decode, [acc | part]) _ in unquote(0x00..0x1F), _rest -> error(original, skip + len) _, rest -> - string(rest, original, skip, stack, key_decode, string_decode, acc, len + 1) + string(rest, original, skip, stack, decode, acc, len + 1) <> when char <= 0x7FF -> - string(rest, original, skip, stack, key_decode, string_decode, acc, len + 2) + string(rest, original, skip, stack, decode, acc, len + 2) <> when char <= 0xFFFF -> - string(rest, original, skip, stack, key_decode, string_decode, acc, len + 3) + string(rest, original, skip, stack, decode, acc, len + 3) <<_char::utf8, rest::bits>> -> - string(rest, original, skip, stack, key_decode, string_decode, acc, len + 4) + string(rest, original, skip, stack, decode, acc, len + 4) <<_::bits>> -> empty_error(original, skip + len) end end - defp escape(data, original, skip, stack, key_decode, string_decode, acc) do + defp escape(data, original, skip, stack, decode, acc) do bytecase data do _ in 'b', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\b'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\b'], 0) _ in 't', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\t'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\t'], 0) _ in 'n', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\n'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\n'], 0) _ in 'f', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\f'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\f'], 0) _ in 'r', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\r'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\r'], 0) _ in '"', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\"'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\"'], 0) _ in '/', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '/'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '/'], 0) _ in '\\', rest -> - string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\\'], 0) + string(rest, original, skip + 2, stack, decode, [acc | '\\'], 0) _ in 'u', rest -> - escapeu(rest, original, skip, stack, key_decode, string_decode, acc) + escapeu(rest, original, skip, stack, decode, acc) _, _rest -> error(original, skip + 1) <<_::bits>> -> @@ -434,8 +440,8 @@ defmodule Jason.Decoder do end end - defmacro escapeu_first(int, last, rest, original, skip, stack, key_decode, string_decode, acc) do - clauses = escapeu_first_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc) + defmacro escapeu_first(int, last, rest, original, skip, stack, decode, acc) do + clauses = escapeu_first_clauses(last, rest, original, skip, stack, decode, acc) quote location: :keep do case unquote(int) do unquote(clauses ++ token_error_clause(original, skip, 6)) @@ -443,20 +449,20 @@ defmodule Jason.Decoder do end end - defp escapeu_first_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc) do + defp escapeu_first_clauses(last, rest, original, skip, stack, decode, acc) do for {int, first} <- unicode_escapes(), not (first in 0xDC..0xDF) do - escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc) + escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc) end end - defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc) + defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc) when first in 0xD8..0xDB do hi = quote bind_quoted: [first: first, last: last] do 0x10000 + ((((first &&& 0x03) <<< 8) + last) <<< 10) end - args = [rest, original, skip, stack, key_decode, string_decode, acc, hi] + args = [rest, original, skip, stack, decode, acc, hi] [clause] = quote location: :keep do unquote(int) -> escape_surrogate(unquote_splicing(args)) @@ -464,7 +470,7 @@ defmodule Jason.Decoder do clause end - defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc) + defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc) when first <= 0x00 do skip = quote do: (unquote(skip) + 6) acc = @@ -479,7 +485,7 @@ defmodule Jason.Decoder do [acc, byte1, byte2] end end - args = [rest, original, skip, stack, key_decode, string_decode, acc, 0] + args = [rest, original, skip, stack, decode, acc, 0] [clause] = quote location: :keep do unquote(int) -> string(unquote_splicing(args)) @@ -487,7 +493,7 @@ defmodule Jason.Decoder do clause end - defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc) + defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc) when first <= 0x07 do skip = quote do: (unquote(skip) + 6) acc = @@ -497,7 +503,7 @@ defmodule Jason.Decoder do byte2 = (0b10 <<< 6) + (last &&& 0b111111) [acc, byte1, byte2] end - args = [rest, original, skip, stack, key_decode, string_decode, acc, 0] + args = [rest, original, skip, stack, decode, acc, 0] [clause] = quote location: :keep do unquote(int) -> string(unquote_splicing(args)) @@ -505,7 +511,7 @@ defmodule Jason.Decoder do clause end - defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc) + defp escapeu_first_clause(int, first, last, rest, original, skip, stack, decode, acc) when first <= 0xFF do skip = quote do: (unquote(skip) + 6) acc = @@ -516,7 +522,7 @@ defmodule Jason.Decoder do byte3 = (0b10 <<< 6) + (last &&& 0b111111) [acc, byte1, byte2, byte3] end - args = [rest, original, skip, stack, key_decode, string_decode, acc, 0] + args = [rest, original, skip, stack, decode, acc, 0] [clause] = quote location: :keep do unquote(int) -> string(unquote_splicing(args)) @@ -543,9 +549,9 @@ defmodule Jason.Decoder do end end - defmacro escapeu_surrogate(int, last, rest, original, skip, stack, key_decode, string_decode, acc, + defmacro escapeu_surrogate(int, last, rest, original, skip, stack, decode, acc, hi) do - clauses = escapeu_surrogate_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc, hi) + clauses = escapeu_surrogate_clauses(last, rest, original, skip, stack, decode, acc, hi) quote location: :keep do case unquote(int) do unquote(clauses ++ token_error_clause(original, skip, 12)) @@ -553,22 +559,22 @@ defmodule Jason.Decoder do end end - defp escapeu_surrogate_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc, hi) do + defp escapeu_surrogate_clauses(last, rest, original, skip, stack, decode, acc, hi) do digits1 = 'Dd' digits2 = Stream.concat([?C..?F, ?c..?f]) for {int, first} <- unicode_escapes(digits1, digits2) do - escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc, hi) + escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, decode, acc, hi) end end - defp escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc, hi) do + defp escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, decode, acc, hi) do skip = quote do: unquote(skip) + 12 acc = quote bind_quoted: [acc: acc, first: first, last: last, hi: hi] do lo = ((first &&& 0x03) <<< 8) + last [acc | <<(hi + lo)::utf8>>] end - args = [rest, original, skip, stack, key_decode, string_decode, acc, 0] + args = [rest, original, skip, stack, decode, acc, 0] [clause] = quote do unquote(int) -> @@ -578,12 +584,12 @@ defmodule Jason.Decoder do end end - defp escapeu(<>, original, skip, stack, key_decode, string_decode, acc) do + defp escapeu(<>, original, skip, stack, decode, acc) do require Unescape last = escapeu_last(int2, original, skip) - Unescape.escapeu_first(int1, last, rest, original, skip, stack, key_decode, string_decode, acc) + Unescape.escapeu_first(int1, last, rest, original, skip, stack, decode, acc) end - defp escapeu(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _acc) do + defp escapeu(<<_rest::bits>>, original, skip, _stack, _decode, _acc) do empty_error(original, skip) end @@ -595,12 +601,12 @@ defmodule Jason.Decoder do end defp escape_surrogate(<>, original, - skip, stack, key_decode, string_decode, acc, hi) do + skip, stack, decode, acc, hi) do require Unescape last = escapeu_last(int2, original, skip + 6) - Unescape.escapeu_surrogate(int1, last, rest, original, skip, stack, key_decode, string_decode, acc, hi) + Unescape.escapeu_surrogate(int1, last, rest, original, skip, stack, decode, acc, hi) end - defp escape_surrogate(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _acc, _hi) do + defp escape_surrogate(<<_rest::bits>>, original, skip, _stack, _decode, _acc, _hi) do error(original, skip + 6) end @@ -611,7 +617,7 @@ defmodule Jason.Decoder do token_error(token, skip) end - defp error(<<_rest::bits>>, _original, skip, _stack, _key_decode, _string_decode) do + defp error(<<_rest::bits>>, _original, skip, _stack, _decode) do throw {:position, skip - 1} end @@ -632,28 +638,28 @@ defmodule Jason.Decoder do throw {:token, binary_part(token, position, len), position} end - @compile {:inline, continue: 7} - defp continue(rest, original, skip, stack, key_decode, string_decode, value) do + @compile {:inline, continue: 6} + defp continue(rest, original, skip, stack, decode, value) do case stack do [@terminate | stack] -> - terminate(rest, original, skip, stack, key_decode, string_decode, value) + terminate(rest, original, skip, stack, decode, value) [@array | stack] -> - array(rest, original, skip, stack, key_decode, string_decode, value) + array(rest, original, skip, stack, decode, value) [@key | stack] -> - key(rest, original, skip, stack, key_decode, string_decode, value) + key(rest, original, skip, stack, decode, value) [@object | stack] -> - object(rest, original, skip, stack, key_decode, string_decode, value) + object(rest, original, skip, stack, decode, value) end end - defp terminate(<>, original, skip, stack, key_decode, string_decode, value) + defp terminate(<>, original, skip, stack, decode, value) when byte in '\s\n\r\t' do - terminate(rest, original, skip + 1, stack, key_decode, string_decode, value) + terminate(rest, original, skip + 1, stack, decode, value) end - defp terminate(<<>>, _original, _skip, _stack, _key_decode, _string_decode, value) do + defp terminate(<<>>, _original, _skip, _stack, _decode, value) do value end - defp terminate(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _value) do + defp terminate(<<_rest::bits>>, original, skip, _stack, _decode, _value) do error(original, skip) end end