aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ic/src/ic_array_java.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ic/src/ic_array_java.erl')
-rw-r--r--lib/ic/src/ic_array_java.erl295
1 files changed, 295 insertions, 0 deletions
diff --git a/lib/ic/src/ic_array_java.erl b/lib/ic/src/ic_array_java.erl
new file mode 100644
index 0000000000..e21d646bf5
--- /dev/null
+++ b/lib/ic/src/ic_array_java.erl
@@ -0,0 +1,295 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ic_array_java).
+
+-export([gen/4]).
+
+-include("ic.hrl").
+-include("icforms.hrl").
+
+
+gen(G, N, X, Array) when is_record(X, member) ->
+ ArrayName = ic_forms:get_java_id(Array),
+ ArrayElement = ic_forms:get_type(X),
+ emit_holder_class(G, N, X, Array, ArrayName, ArrayElement),
+ emit_helper_class(G, N, X, Array, ArrayName, ArrayElement);
+gen(G, N, X, Array) when is_record(X, case_dcl) ->
+ ArrayName = ic_forms:get_java_id(Array),
+ ArrayElement = ic_forms:get_type(X),
+ emit_holder_class(G, N, X, Array, ArrayName, ArrayElement),
+ emit_helper_class(G, N, X, Array, ArrayName, ArrayElement);
+gen(G, N, X, Array) ->
+ ArrayName = ic_forms:get_java_id(Array),
+ ArrayElement = ic_forms:get_body(X),
+ emit_holder_class(G, N, X, Array, ArrayName, ArrayElement),
+ emit_helper_class(G, N, X, Array, ArrayName, ArrayElement).
+
+
+
+%%-----------------------------------------------------------------
+%% Func: emit_holder_class/4
+%%-----------------------------------------------------------------
+emit_holder_class(G, N, _X, Array, ArrayName, ArrayElement) ->
+ SName = string:concat(ArrayName, "Holder"),
+ {Fd, _}= ic_file:open_java_file(G, N, SName),
+
+ ArrayElementName = ic_java_type:getType(G, N, ArrayElement),
+ EmptyDim = arrayEmptyDim(Array),
+
+ ic_codegen:emit(Fd, "final public class ~sHolder {\n",[ArrayName]),
+
+ ic_codegen:emit(Fd, " // instance variables\n", []),
+ ic_codegen:emit(Fd, " public ~s~s value;\n\n",
+ [ArrayElementName,EmptyDim]),
+
+ ic_codegen:emit(Fd, " // constructors\n", []),
+ ic_codegen:emit(Fd, " public ~sHolder() {}\n", [ArrayName]),
+ ic_codegen:emit(Fd, " public ~sHolder(~s~s initial) {\n",
+ [ArrayName,ArrayElementName,EmptyDim]),
+ ic_codegen:emit(Fd, " value = initial;\n", []),
+ ic_codegen:emit(Fd, " }\n", []),
+ ic_codegen:nl(Fd),
+
+ ic_codegen:emit(Fd, " // methods\n", []),
+
+ ic_codegen:emit(Fd, " public void _marshal(~sOtpOutputStream out)\n", [?ERLANGPACKAGE]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n"),
+ ic_codegen:emit(Fd, " ~sHelper.marshal(out, value);\n", [ArrayName]),
+ ic_codegen:emit(Fd, " }\n"),
+ ic_codegen:nl(Fd),
+ ic_codegen:emit(Fd, " public void _unmarshal(~sOtpInputStream in)\n", [?ERLANGPACKAGE]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n"),
+ ic_codegen:emit(Fd, " value = ~sHelper.unmarshal(in);\n", [ArrayName]),
+ ic_codegen:emit(Fd, " }\n", []),
+ ic_codegen:nl(Fd),
+
+ ic_codegen:emit(Fd, "}\n", []),
+ file:close(Fd).
+
+
+%%-----------------------------------------------------------------
+%% Func: emit_helper_class/4
+%%-----------------------------------------------------------------
+emit_helper_class(G, N, X, Array, ArrayName, ArrayElement) ->
+ SName = string:concat(ArrayName, "Helper"),
+ {Fd, _}= ic_file:open_java_file(G, N, SName),
+
+ ArrayElementName = ic_java_type:getType(G, N, ArrayElement),
+ EmptyDim = arrayEmptyDim(Array),
+% Dim = arrayDim(G,N,Array),
+
+ ic_codegen:emit(Fd, "public class ~sHelper {\n",[ArrayName]),
+
+ ic_codegen:emit(Fd, " // constructors\n"),
+ ic_codegen:emit(Fd, " private ~sHelper() {}\n\n", [ArrayName]),
+
+ ic_codegen:emit(Fd, " // methods\n"),
+
+ ic_codegen:emit(Fd, " public static void marshal(~sOtpOutputStream _out, ~s~s _value)\n",
+ [?ERLANGPACKAGE,ArrayElementName,EmptyDim]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"),
+ emit_array_marshal_loop(G,N,X,Array,ArrayElement,Fd),
+ ic_codegen:emit(Fd, " }\n"),
+ ic_codegen:nl(Fd),
+ ic_codegen:emit(Fd, " public static ~s~s unmarshal(~sOtpInputStream _in)\n",
+ [ArrayElementName,EmptyDim,?ERLANGPACKAGE]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"),
+ ic_codegen:emit(Fd, " ~s~s _value = new ~s;\n\n",
+ [ArrayElementName,EmptyDim,ic_java_type:getFullType(G, N, X, Array)]),
+ emit_array_unmarshal_loop(G,N,X,Array,ArrayElement,Fd),
+ ic_codegen:emit(Fd, " return _value;\n"),
+ ic_codegen:emit(Fd, " }\n\n"),
+
+ ic_codegen:emit(Fd, " public static String id() {\n", []),
+ ic_codegen:emit(Fd, " return ~p;\n",[ictk:get_IR_ID(G, N, Array)]),
+ ic_codegen:emit(Fd, " }\n\n"),
+
+ ic_codegen:emit(Fd, " public static String name() {\n", []),
+ ic_codegen:emit(Fd, " return ~p;\n",[ArrayName]),
+ ic_codegen:emit(Fd, " }\n\n"),
+
+ ic_jbe:emit_type_function(G, N, X, Fd),
+
+ ic_codegen:emit(Fd, " public static void insert(~sAny _any, ~s~s _this)\n",
+ [?ICPACKAGE,ArrayElementName,EmptyDim]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"),
+
+ ic_codegen:emit(Fd, " ~sOtpOutputStream _os = \n",[?ERLANGPACKAGE]),
+ ic_codegen:emit(Fd, " new ~sOtpOutputStream();\n\n",[?ERLANGPACKAGE]),
+
+ ic_codegen:emit(Fd, " _any.type(type());\n"),
+ ic_codegen:emit(Fd, " marshal(_os, _this);\n"),
+ ic_codegen:emit(Fd, " _any.insert_Streamable(_os);\n"),
+ ic_codegen:emit(Fd, " }\n\n"),
+
+ ic_codegen:emit(Fd, " public static ~s~s extract(~sAny _any)\n",
+ [ArrayElementName,EmptyDim,?ICPACKAGE]),
+ ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"),
+
+ ic_codegen:emit(Fd, " return unmarshal(_any.extract_Streamable());\n"),
+ ic_codegen:emit(Fd, " }\n\n"),
+
+ ic_codegen:emit(Fd, "}\n"),
+ file:close(Fd).
+
+
+
+
+emit_array_marshal_loop(G,N,X,Array,AEl,Fd) ->
+ DimList = mk_array_dim_list(G,N,Array),
+ emit_array_marshal_loop_1(G,N,X,Array,AEl,DimList,0,Fd).
+
+
+emit_array_marshal_loop_1(G,N,X,Array,AEl,[D],C,Fd) ->
+
+ DimList = mk_array_dim_list(G,N,Array),
+
+ ic_codegen:emit(Fd, " _out.write_tuple_head(~s);\n\n",[D]),
+
+ ic_codegen:emit(Fd, " for(int _tmp~p = 0; _tmp~p < ~s; _tmp~p++)\n",[C,C,D,C]),
+
+ case ic_java_type:isBasicType(G, N, AEl) of
+ true ->
+ ic_codegen:emit(Fd, " _out~s(_value",
+ [ic_java_type:marshalFun(G, N, X, AEl)]);
+ false ->
+ ic_codegen:emit(Fd, " ~s(_out, _value",
+ [ic_java_type:marshalFun(G, N, X, AEl)])
+ end,
+
+ emit_array_dimensions(DimList,0,Fd),
+
+ ic_codegen:emit(Fd, ");\n\n");
+
+emit_array_marshal_loop_1(G,N,X,Array,AEl,[D|Ds],C,Fd) ->
+% DimList = mk_array_dim_list(G,N,Array),
+
+ ic_codegen:emit(Fd, " _out.write_tuple_head(~s);\n\n",[D]),
+
+ ic_codegen:emit(Fd, " for(int _tmp~p = 0; _tmp~p < ~s; _tmp~p++) {\n",[C,C,D,C]),
+
+ emit_array_marshal_loop_1(G,N,X,Array,AEl,Ds,C+1,Fd),
+
+ ic_codegen:emit(Fd, " }\n\n").
+
+
+
+
+
+emit_array_unmarshal_loop(G,N,X,Array,AEl,Fd) ->
+ DimList = mk_array_dim_list(G,N,Array),
+ case length(DimList) > 0 of
+ true ->
+ ic_codegen:emit(Fd, " _in.read_tuple_head();\n\n"),
+
+ ic_codegen:emit(Fd, " for(int _tmp0 = 0; _tmp0 < ~s; _tmp0++) {\n\n",[hd(DimList)]),
+ emit_array_unmarshal_loop_1(G,N,X,Array,AEl,tl(DimList),1,Fd),
+ ic_codegen:emit(Fd, " }\n\n");
+ false ->
+ emit_array_unmarshal_loop_1(G,N,X,Array,AEl,DimList,0,Fd)
+ end.
+
+emit_array_unmarshal_loop_1(G,N,X,_Array,AEl,[],1,Fd) -> %% One dimensional array
+ case ic_java_type:isBasicType(G, N, AEl) of
+ true ->
+ ic_codegen:emit(Fd, " _value[_tmp0] = _in~s;\n",
+ [ic_java_type:unMarshalFun(G, N, X, AEl)]);
+ false ->
+ ic_codegen:emit(Fd, " _value[_tmp0] = ~s.unmarshal(_in);\n\n",
+ [ic_java_type:getUnmarshalType(G, N, X, AEl)])
+ end;
+emit_array_unmarshal_loop_1(G,N,X,Array,AEl,[],_C,Fd) ->
+ DimList = mk_array_dim_list(G,N,Array),
+ ic_codegen:emit(Fd, " _value"),
+ emit_array_dimensions(DimList,0,Fd),
+ case ic_java_type:isBasicType(G,N,AEl) of
+ true ->
+ ic_codegen:emit(Fd, " = _in~s;\n",
+ [ic_java_type:unMarshalFun(G, N, X, AEl)]);
+ false ->
+ ic_codegen:emit(Fd, " = ~s.unmarshal(_in);\n",
+ [ic_java_type:getUnmarshalType(G, N, X, AEl)])
+ end;
+emit_array_unmarshal_loop_1(G,N,X,Array,AEl,[D|Ds],C,Fd) ->
+ ic_codegen:emit(Fd, " _in.read_tuple_head();\n\n"),
+
+ ic_codegen:emit(Fd, " for(int _tmp~p = 0; _tmp~p < ~s; _tmp~p++) {\n\n",[C,C,D,C]),
+ emit_array_unmarshal_loop_1(G,N,X,Array,AEl,Ds,C+1,Fd),
+ ic_codegen:emit(Fd, " }\n").
+
+
+
+
+
+%%---------------------------------------------------
+%% Utilities
+%%---------------------------------------------------
+
+mk_array_dim_list(G,N,Array) ->
+ mk_array_dim_list2(G,N,Array#array.size).
+
+
+mk_array_dim_list2(_G,_N,[]) ->
+ [];
+
+mk_array_dim_list2(G,N,[D |Ds]) when is_record(D,scoped_id) ->
+ {FSN, _, _, _} = ic_symtab:get_full_scoped_name(G, N, D),
+ [ ic_util:to_dot(G,FSN) | mk_array_dim_list2(G,N,Ds)];
+
+mk_array_dim_list2(G,N,[D |Ds]) ->
+ [ic_util:eval_java(G,N,D) | mk_array_dim_list2(G,N,Ds)].
+
+
+
+%% Array dimension string
+%arrayDim(G,N,X) ->
+% arrayDim2(G,N,X#array.size).
+
+%arrayDim2(_G,_N,[]) ->
+% "";
+%arrayDim2(G,N,[D|Ds]) when record(D,scoped_id) ->
+% {FSN, _, _, _} = ic_symtab:get_full_scoped_name(G, N, D),
+% "[" ++ ic_util:to_dot(G,FSN) ++ "]" ++ arrayDim2(G,N,Ds);
+%arrayDim2(G,N,[D|Ds]) ->
+% "[" ++ ic_util:eval_java(G,N,D) ++ "]" ++ arrayDim2(G,N,Ds).
+
+
+%% Array Empty dimension string
+arrayEmptyDim(X) ->
+ arrayEmptyDim2(X#array.size).
+
+arrayEmptyDim2([_D]) ->
+ "[]";
+arrayEmptyDim2([_D |Ds]) ->
+ "[]" ++ arrayEmptyDim2(Ds).
+
+
+emit_array_dimensions([_D],C,Fd) ->
+ ic_codegen:emit(Fd, "[_tmp~p]",[C]);
+emit_array_dimensions([_D|Ds],C,Fd) ->
+ ic_codegen:emit(Fd, "[_tmp~p]",[C]),
+ emit_array_dimensions(Ds,C+1,Fd).
+
+
+
+
+
+