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/13 20:45:32 UTC

[33/43] jiffy commit: updated refs/heads/upstream to 446e284

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/upstream
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