Commits

Anonymous committed 69ec93d

Merging changes from erlang_js

  • Participants
  • Parent commits e29d645

Comments (0)

Files changed (10)

apps/erlang_js/Makefile

 	./rebar compile
 
 clean:
-	rm -rf tests_ebin
+	rm -rf tests_ebin docs
 	./rebar clean
 	cd c_src;make jsclean
 
 	@cd tests;erl -make
 	@erl -noshell -boot start_sasl -pa ebin -pa tests_ebin -s erlang_js -eval 'test_suite:test().' -s init stop
 	@rm -f ebin/test_* ebin/*_tests.erl
+
+docs: all
+	@mkdir -p docs
+	@ERL_LIBS=`cd ..;pwd`;erl -noshell -eval 'edoc:application(erlang_js, [{dir, "docs"}]), init:stop().'

apps/erlang_js/ebin/erlang_js.app

 {application, erlang_js,
  [{description,  "Interface between BEAM and JS"},
   {vsn,          "0.1"},
-  {modules,      [erlang_js, erlang_js_sup, js, js_benchmark, js_cache, js_driver, js_drv_comm, js_memory, js_json, js_mochinum]},
+  {modules,      [erlang_js, erlang_js_sup, js, js_benchmark, js_cache, js_driver, js_drv_comm, js_memory, js_mochijson2, js_mochinum]},
   {registered,   [erlang_js_sup, js_cache]},
   {applications, [kernel, stdlib, sasl]},
   {mod, {erlang_js, []}}]}.

apps/erlang_js/src/erlang_js.erl

 %%    See the License for the specific language governing permissions and
 %%    limitations under the License.
 
+%% @ doc This module is the entry point to start erlang_js as an OTP application.
 -module(erlang_js).
 
 -behaviour(application).
 %% Application callbacks
 -export([start/0, start/2, stop/1]).
 
+
+%% @spec start() -> ok | {error, any()}
+%% @doc Starts the erlang_js OTP application and all
+%% dependencies. Intended for use with the Erlang VM's
+%% -s option
 start() ->
     start_deps([sasl]),
     application:start(erlang_js).
 
+%% @private
 start(_StartType, _StartArgs) ->
     erlang_js_sup:start_link().
 
+%% @private
 stop(_State) ->
     ok.
 

apps/erlang_js/src/erlang_js_sup.erl

 %%    See the License for the specific language governing permissions and
 %%    limitations under the License.
 
+%% @doc Top level supervisor for erlang_js. It is chiefly responsible for
+%% the js_cache file cache process.
 -module(erlang_js_sup).
 
 -behaviour(supervisor).
 
 -define(SERVER, ?MODULE).
 
+%% @private
 start_link() ->
     supervisor:start_link({local, ?SERVER}, ?MODULE, []).
 
+%% @private
 init([]) ->
     RestartStrategy = one_for_one,
     MaxRestarts = 1000,

apps/erlang_js/src/js.erl

                        false ->
                            VarName
                    end,
-    build_bindings(T, [["var ", FinalVarName, "=", js_json:encode(Value), ";\n"]|Accum]).
+    build_bindings(T, [["var ", FinalVarName, "=", js_mochijson2:encode(Value), ";\n"]|Accum]).
 
 build_arg_list([], Accum) ->
     lists:reverse(Accum);
 build_arg_list([H|[]], Accum) ->
-    build_arg_list([], [js_json:encode(H)|Accum]);
+    build_arg_list([], [js_mochijson2:encode(H)|Accum]);
 build_arg_list([H|T], Accum) ->
-    build_arg_list(T, [[js_json:encode(H), ","]|Accum]).
+    build_arg_list(T, [[js_mochijson2:encode(H), ","]|Accum]).

apps/erlang_js/src/js_benchmark.erl

 %%    See the License for the specific language governing permissions and
 %%    limitations under the License.
 
+%% @doc Utility module for measuring latencies across the Erlang/Javascript
+%% boundary. This module implements a very simple benchmark of defining and
+%% executing a simple Javascript function 1000, 10000, and 100000 times.
+
 -module(js_benchmark).
 
 -define(COUNTS, [1000, 10000, 100000]).
 
 -export([run/0]).
 
+%% @spec run() -> list(int(), int(), int())
+%% @doc Runs the benchmark and returns the average time to
+%% process a function call for each set of iterations in
+%% microseconds.
 run() ->
     application:start(erlang_js),
     {ok, Ctx} = js_driver:new(),
     js_driver:destroy(Ctx),
     Result.
 
+%% @private
 time_calls(Ctx, Count) ->
     io:format("Starting: ~p~n", [Count]),
     Start = erlang:now(),
     do_calls(Ctx, Count),
     timer:now_diff(erlang:now(), Start) / Count.
+
+%% @private
 do_calls(_Ctx, 0) ->
     ok;
 do_calls(Ctx, Count) ->

apps/erlang_js/src/js_cache.erl

 %%    See the License for the specific language governing permissions and
 %%    limitations under the License.
 
+%% @doc This module implements a basic cache. This cache is used to store
+%% files used to initialize each Javascript context. This is helpful because
+%% it prevents erlang_js from accessing the filesystem more than necessary.
+
 -module(js_cache).
 
 -behaviour(gen_server).
 
 -record(state, {cache=gb_trees:empty()}).
 
+%% @private
 start_link() ->
     gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
 
+%% @spec store(any(), any() -> ok
+%% @doc Store a key/value pair
 store(Key, Value) ->
     gen_server:cast(?SERVER, {store, Key, Value}).
 
+%% @spec delete(any()) -> ok
+%% @doc Deletes a key/value pair, if present, from the cache.
 delete(Key) ->
     gen_server:cast(?SERVER, {delete, Key}).
 
+%% @spec fetch(any()) -> any() | not_found
+%% @doc Retrieves a key/value pair from the cache. If the key
+%% is not in the cache, the atom 'not_found' is returned.
 fetch(Key) ->
     gen_server:call(?SERVER, {fetch, Key}).
 
 init([]) ->
     {ok, #state{}}.
 
+% @private
 handle_call({fetch, Key}, _From, #state{cache=Cache}=State) ->
     Result = case gb_trees:lookup(Key, Cache) of
                  {value, Value} ->
              end,
     {reply, Result, State};
 
+% @private
 handle_call(_Request, _From, State) ->
     {reply, ignore, State}.
 
+% @private
 handle_cast({store, Key, Value}, #state{cache=Cache}=State) ->
     {noreply, State#state{cache=gb_trees:enter(Key, Value, Cache)}};
 
+% @private
 handle_cast({delete, Key}, #state{cache=Cache}=State) ->
     {noreply, State#state{cache=gb_trees:delete(Key, Cache)}};
 
+% @private
 handle_cast(_Msg, State) ->
     {noreply, State}.
 
+% @private
 handle_info(_Info, State) ->
     {noreply, State}.
 
+% @private
 terminate(_Reason, _State) ->
     ok.
 
+% @private
 code_change(_OldVsn, State, _Extra) ->
     {ok, State}.
-
-%% Internal functions

apps/erlang_js/src/js_driver.erl

                                            is_binary(Js) ->
     case call_driver(Ctx, "dj", [FileName, Js], Timeout) of
         {error, ErrorJson} when is_binary(ErrorJson) ->
-            {struct, [{<<"error">>, {struct, Error}}]} = js_json:decode(ErrorJson),
+            {struct, [{<<"error">>, {struct, Error}}]} = js_mochijson2:decode(ErrorJson),
             {error, Error};
         ok ->
             ok
 eval_js(Ctx, Js, Timeout) when is_binary(Js) ->
     case call_driver(Ctx, "ej", [<<"<unnamed>">>, jsonify(Js)], Timeout) of
         {ok, Result} ->
-            {ok, js_json:decode(Result)};
+            {ok, js_mochijson2:decode(Result)};
         {error, ErrorJson} when is_binary(ErrorJson) ->
-            case js_json:decode(ErrorJson) of
+            case js_mochijson2:decode(ErrorJson) of
                 {struct, [{<<"error">>, {struct, Error}}]} ->
                     {error, Error};
                 {struct, [{<<"error">>, Error}]} ->

apps/erlang_js/tests/eval_tests.erl

        fun() ->
                P = test_util:get_thing(),
                ?assertMatch(ok, js:define(P, <<"function get_first(data) { return data[\"first\"]; };">>)),
-               Data = [{<<"first">>, <<"abc">>}],
+               Data = {struct, [{<<"first">>, <<"abc">>}]},
                ?assertMatch({ok, <<"abc">>}, js:call(P, <<"get_first">>, [Data])),
                erlang:unlink(P) end]}].
 
+json_test_() ->
+  [fun() ->
+       Struct = {struct, [{<<"test">>, <<"1">>}]},
+       ?assertMatch(Struct, js_mochijson2:decode(js_mochijson2:encode(Struct))) end].
+
 error_test_() ->
     [{setup, fun test_util:port_setup/0,
       fun test_util:port_teardown/1,

apps/erlang_js/tests/test_suite.erl

 
 all_test_() ->
   [{module, driver_tests},
-   {module, eval_tests},
-   {module, json_tests}].
+   {module, eval_tests}].