You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by kx...@apache.org on 2015/07/29 00:42:47 UTC
[22/54] jiffy commit: updated refs/heads/master to ef77de4
Persist the `val` register across yield
The `val` variable is a register value that we need to be able to return
at any time from `decode_iter`. If it happened that a yield was
triggered while processing trailing whitespace the lack of persistance
caused decode to return a term intialized from a random integer value.
Obviously the Erlang VM did not enjoy this.
Thanks to @michalpalka for the report.
Fixes #66
Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/5cd89c1e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/5cd89c1e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/5cd89c1e
Branch: refs/heads/master
Commit: 5cd89c1eda3801bdef790b1e7c0e09259332c0fc
Parents: f9095c5
Author: Paul J. Davis <pa...@gmail.com>
Authored: Sat Aug 23 07:20:37 2014 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Sat Aug 23 07:20:37 2014 -0500
----------------------------------------------------------------------
c_src/decoder.c | 22 ++++++++++++----------
c_src/jiffy.c | 2 +-
src/jiffy.erl | 14 +++++++-------
test/jiffy_13_whitespace_tests.erl | 16 ++++++++++++++++
4 files changed, 36 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5cd89c1e/c_src/decoder.c
----------------------------------------------------------------------
diff --git a/c_src/decoder.c b/c_src/decoder.c
index e7dc48b..ad3e8d3 100644
--- a/c_src/decoder.c
+++ b/c_src/decoder.c
@@ -675,7 +675,7 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
Decoder* d;
jiffy_st* st = (jiffy_st*) enif_priv_data(env);
- ERL_NIF_TERM tmp_argv[4];
+ ERL_NIF_TERM tmp_argv[5];
ERL_NIF_TERM opts;
ERL_NIF_TERM val;
@@ -690,8 +690,9 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
tmp_argv[0] = argv[0];
tmp_argv[1] = enif_make_resource(env, d);
- tmp_argv[2] = enif_make_list(env, 0);
+ tmp_argv[2] = st->atom_error;
tmp_argv[3] = enif_make_list(env, 0);
+ tmp_argv[4] = enif_make_list(env, 0);
enif_release_resource(d);
@@ -716,7 +717,7 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
}
- return decode_iter(env, 4, tmp_argv);
+ return decode_iter(env, 5, tmp_argv);
}
ERL_NIF_TERM
@@ -729,25 +730,25 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ERL_NIF_TERM objs;
ERL_NIF_TERM curr;
- ERL_NIF_TERM val;
+ ERL_NIF_TERM val = argv[2];
ERL_NIF_TERM ret;
size_t start;
- if(argc != 4) {
+ if(argc != 5) {
return enif_make_badarg(env);
} else if(!enif_inspect_binary(env, argv[0], &bin)) {
return enif_make_badarg(env);
} else if(!enif_get_resource(env, argv[1], st->res_dec, (void**) &d)) {
return enif_make_badarg(env);
- } else if(!enif_is_list(env, argv[2])) {
- return enif_make_badarg(env);
} else if(!enif_is_list(env, argv[3])) {
return enif_make_badarg(env);
+ } else if(!enif_is_list(env, argv[4])) {
+ return enif_make_badarg(env);
}
dec_init(d, env, argv[0], &bin);
- objs = argv[2];
- curr = argv[3];
+ objs = argv[3];
+ curr = argv[4];
//fprintf(stderr, "Parsing:\r\n");
start = d->i;
@@ -755,10 +756,11 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
//fprintf(stderr, "state: %d\r\n", dec_curr(d));
if(should_yield(d->i - start, d->bytes_per_iter)) {
consume_timeslice(env, d->i - start, d->bytes_per_iter);
- return enif_make_tuple4(
+ return enif_make_tuple5(
env,
st->atom_iter,
argv[1],
+ val,
objs,
curr
);
http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5cd89c1e/c_src/jiffy.c
----------------------------------------------------------------------
diff --git a/c_src/jiffy.c b/c_src/jiffy.c
index 205de91..31aa854 100644
--- a/c_src/jiffy.c
+++ b/c_src/jiffy.c
@@ -78,7 +78,7 @@ unload(ErlNifEnv* env, void* priv)
static ErlNifFunc funcs[] =
{
{"nif_decode_init", 2, decode_init},
- {"nif_decode_iter", 4, decode_iter},
+ {"nif_decode_iter", 5, decode_iter},
{"nif_encode_init", 2, encode_init},
{"nif_encode_iter", 3, encode_iter}
};
http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5cd89c1e/src/jiffy.erl
----------------------------------------------------------------------
diff --git a/src/jiffy.erl b/src/jiffy.erl
index 9642b25..23a0c9d 100644
--- a/src/jiffy.erl
+++ b/src/jiffy.erl
@@ -18,8 +18,8 @@ decode(Data, Opts) when is_binary(Data), is_list(Opts) ->
throw(Error);
{partial, EJson} ->
finish_decode(EJson);
- {iter, Decoder, Objs, Curr} ->
- decode_loop(Data, Decoder, Objs, Curr);
+ {iter, Decoder, Val, Objs, Curr} ->
+ decode_loop(Data, Decoder, Val, Objs, Curr);
EJson ->
EJson
end;
@@ -120,14 +120,14 @@ init() ->
erlang:load_nif(filename:join(PrivDir, "jiffy"), 0).
-decode_loop(Data, Decoder, Objs, Curr) ->
- case nif_decode_iter(Data, Decoder, Objs, Curr) of
+decode_loop(Data, Decoder, Val, Objs, Curr) ->
+ case nif_decode_iter(Data, Decoder, Val, Objs, Curr) of
{error, _} = Error ->
throw(Error);
{partial, EJson} ->
finish_decode(EJson);
- {iter, NewDecoder, NewObjs, NewCurr} ->
- decode_loop(Data, NewDecoder, NewObjs, NewCurr);
+ {iter, NewDecoder, NewVal, NewObjs, NewCurr} ->
+ decode_loop(Data, NewDecoder, NewVal, NewObjs, NewCurr);
EJson ->
EJson
end.
@@ -156,7 +156,7 @@ not_loaded(Line) ->
nif_decode_init(_Data, _Opts) ->
?NOT_LOADED.
-nif_decode_iter(_Data, _Decoder, _, _) ->
+nif_decode_iter(_Data, _Decoder, _, _, _) ->
?NOT_LOADED.
nif_encode_init(_Data, _Options) ->
http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5cd89c1e/test/jiffy_13_whitespace_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_13_whitespace_tests.erl b/test/jiffy_13_whitespace_tests.erl
new file mode 100644
index 0000000..9261b6e
--- /dev/null
+++ b/test/jiffy_13_whitespace_tests.erl
@@ -0,0 +1,16 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_13_whitespace_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+
+trailing_whitespace_test_() ->
+ Str = [<<"{\"a\":\"b\"}">>, gen_ws(2040)],
+ Obj = {[{<<"a">>, <<"b">>}]},
+ ?_assertEqual(Obj, jiffy:decode(Str)).
+
+
+gen_ws(N) ->
+ [" " || _ <- lists:seq(1, N)].
\ No newline at end of file