[m-rev.] diff: restore java mutables
Peter Wang
novalazy at gmail.com
Mon Aug 24 13:35:00 AEST 2009
Branches: main
The recent changes to support warnings about non-contiguous clauses broke
mutable support in Java. The problem was that we generated both a foreign
procedure called "get_<var>" and a clause called "get_<var>", due to sharing
code with the C backends.
compiler/make_hlds_passes.m:
Rename the foreign procs generated for Java to "unsafe_get_<var>" and
"unsafe_set_<var>", to align the Java backend with the C backends.
compiler/prog_mutable.m:
Update the description of the mutables transformation for Java.
diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index 7d91c0e..849055f 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -515,13 +515,18 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
(
CompilationTarget = target_c,
WantPreInitDecl = yes,
- WantUnsafeAccessAndLockDecls = yes
+ WantLockDecls = yes,
+ WantUnsafeAccessDecls = yes
;
- ( CompilationTarget = target_erlang
- ; CompilationTarget = target_java
- ),
+ CompilationTarget = target_java,
+ WantPreInitDecl = no,
+ WantLockDecls = no,
+ WantUnsafeAccessDecls = yes
+ ;
+ CompilationTarget = target_erlang,
WantPreInitDecl = no,
- WantUnsafeAccessAndLockDecls = no
+ WantLockDecls = no,
+ WantUnsafeAccessDecls = no
;
( CompilationTarget = target_il
; CompilationTarget = target_asm
@@ -529,7 +534,8 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
),
% Not supported yet.
WantPreInitDecl = yes,
- WantUnsafeAccessAndLockDecls = yes
+ WantLockDecls = yes,
+ WantUnsafeAccessDecls = yes
),
% Create the mutable initialisation predicate.
@@ -555,13 +561,18 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
% Create the primitive access and locking predicates.
(
- WantUnsafeAccessAndLockDecls = yes,
+ WantLockDecls = yes,
LockPredDeclItem = lock_pred_decl(ModuleName, Name, Context),
UnlockPredDecl = unlock_pred_decl(ModuleName, Name, Context),
add_item_decl_pass_1(LockPredDeclItem, _, Status, _,
!ModuleInfo, !Specs),
add_item_decl_pass_1(UnlockPredDecl, _, Status, _,
- !ModuleInfo, !Specs),
+ !ModuleInfo, !Specs)
+ ;
+ WantLockDecls = no
+ ),
+ (
+ WantUnsafeAccessDecls = yes,
UnsafeGetPredDeclItem = unsafe_get_pred_decl(ModuleName, Name,
Type, Inst, Context),
UnsafeSetPredDeclItem = unsafe_set_pred_decl(ModuleName, Name,
@@ -571,7 +582,7 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
add_item_decl_pass_1(UnsafeSetPredDeclItem, _, Status, _,
!ModuleInfo, !Specs)
;
- WantUnsafeAccessAndLockDecls = no
+ WantUnsafeAccessDecls = no
),
% Create the standard, non-pure access predicates. These are
@@ -840,7 +851,7 @@ add_pass_2_mutable(ItemMutable, Status, !ModuleInfo, !Specs) :-
globals.get_target(Globals, CompilationTarget),
% XXX We don't currently support the foreign_name attribute
- % for languages other than C and Erlang.
+ % for all languages.
(
(
CompilationTarget = target_c,
@@ -2121,53 +2132,49 @@ add_c_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
ForLang, Context, !Status, !ModuleInfo, !QualInfo, !Specs) :-
varset.new_named_var(varset.init, "X", X, ProgVarSet0),
+
LockPredName = mutable_lock_pred_sym_name(ModuleName, MutableName),
UnlockPredName = mutable_unlock_pred_sym_name(ModuleName, MutableName),
- SetPredName = mutable_set_pred_sym_name(ModuleName, MutableName),
+ CallLock = call_expr(LockPredName, [], purity_impure) - Context,
+ CallUnlock = call_expr(UnlockPredName, [], purity_impure) - Context,
+
+ GetterPredName = mutable_unsafe_get_pred_sym_name(ModuleName, MutableName),
+ SetterPredName = mutable_unsafe_set_pred_sym_name(ModuleName, MutableName),
+ CallGetter = call_expr(GetterPredName, [variable(X, Context)],
+ purity_semipure) - Context,
+ CallSetter = call_expr(SetterPredName, [variable(X, context_init)],
+ purity_impure) - Context,
+
GetPredName = mutable_get_pred_sym_name(ModuleName, MutableName),
+ SetPredName = mutable_set_pred_sym_name(ModuleName, MutableName),
(
ForLang = for_c,
- CallLock = call_expr(LockPredName, [], purity_impure) - Context,
- CallUnlock = call_expr(UnlockPredName, [], purity_impure) - Context,
- GetterPredName = mutable_unsafe_get_pred_sym_name(ModuleName,
- MutableName),
- SetterPredName = mutable_unsafe_set_pred_sym_name(ModuleName,
- MutableName)
+ GetBody = goal_list_to_conj(Context, [CallLock, CallGetter,
+ CallUnlock]),
+ StdSetBody = goal_list_to_conj(Context, [CallLock, CallSetter,
+ CallUnlock])
;
ForLang = for_java,
- CallLock = true_expr - Context,
- CallUnlock = true_expr - Context,
- GetterPredName = mutable_get_pred_sym_name(ModuleName, MutableName),
- SetterPredName = mutable_set_pred_sym_name(ModuleName, MutableName)
+ % There are no separate lock predicates for Java; the synchronisation
+ % is performed within the "unsafe" predicates.
+ GetBody = CallGetter,
+ StdSetBody = CallSetter
),
% Construct the semipure get predicate.
- CallGetter = call_expr(GetterPredName, [variable(X, Context)],
- purity_semipure) - Context,
-
- GetBody = goal_list_to_conj(Context, [CallLock, CallGetter, CallUnlock]),
StdGetBody = promise_purity_expr(purity_semipure, GetBody) - Context,
-
- StdGetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet0,
- pf_predicate, GetPredName, [variable(X, context_init)], StdGetBody,
- Context, -1
- ),
- StdSetItem = item_clause(StdSetItemClause),
+ StdGetItemClause = item_clause_info(compiler(mutable_decl),
+ ProgVarSet0, pf_predicate, GetPredName,
+ [variable(X, context_init)], StdGetBody, Context, -1),
+ StdGetItem = item_clause(StdGetItemClause),
add_item_pass_3(StdGetItem, !Status, !ModuleInfo, !QualInfo, !Specs),
% Construct the impure set predicate.
- CallSetter = call_expr(SetterPredName, [variable(X, context_init)],
- purity_impure) - Context,
-
- StdSetBody = goal_list_to_conj(Context,
- [CallLock, CallSetter, CallUnlock]),
-
- StdSetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet0,
- pf_predicate, SetPredName, [variable(X, context_init)], StdSetBody,
- Context, -1
- ),
- StdGetItem = item_clause(StdGetItemClause),
+ StdSetItemClause = item_clause_info(compiler(mutable_decl),
+ ProgVarSet0, pf_predicate, SetPredName,
+ [variable(X, context_init)], StdSetBody, Context, -1),
+ StdSetItem = item_clause(StdSetItemClause),
add_item_pass_3(StdSetItem, !Status, !ModuleInfo, !QualInfo, !Specs),
IOStateInterface = mutable_var_attach_to_io_state(MutAttrs),
@@ -2177,7 +2184,6 @@ add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
% Construct the pure get predicate.
IOGetBody = promise_purity_expr(purity_pure, GetBody) - Context,
-
Ctxt = context_init,
IOGetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet,
pf_predicate, GetPredName,
@@ -2192,9 +2198,7 @@ add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
% We just use the body of impure version and attach a promise_pure
% pragma to the predicate. (The purity pragma was added during
% stage 2.)
-
IOSetBody = StdSetBody,
-
IOSetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet,
pf_predicate, SetPredName,
[variable(X, Ctxt), variable(IO, Ctxt), variable(IO, Ctxt)],
@@ -2399,7 +2403,7 @@ add_java_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
"\tsynchronized (" ++ MutableMutexVarName ++ ") {\n" ++
"\t\tX = " ++ TargetMutableName ++ ";\n\t}\n",
GetForeignProc = pragma_foreign_proc(GetAttrs,
- mutable_get_pred_sym_name(ModuleName, MutableName),
+ mutable_unsafe_get_pred_sym_name(ModuleName, MutableName),
pf_predicate,
[pragma_var(X, "X", out_mode(Inst), BoxPolicy)],
ProgVarSet,
@@ -2430,7 +2434,7 @@ add_java_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
SetCode = "\tsynchronized (" ++ MutableMutexVarName ++ ") {\n" ++
"\t\t" ++ TargetMutableName ++ "= X;\n\t}\n",
SetForeignProc = pragma_foreign_proc(SetAttrs,
- mutable_set_pred_sym_name(ModuleName, MutableName),
+ mutable_unsafe_set_pred_sym_name(ModuleName, MutableName),
pf_predicate,
[pragma_var(X, "X", in_mode(Inst), BoxPolicy)],
ProgVarSet,
diff --git a/compiler/prog_mutable.m b/compiler/prog_mutable.m
index 939cac9..9c96f5a 100644
--- a/compiler/prog_mutable.m
+++ b/compiler/prog_mutable.m
@@ -234,10 +234,14 @@
% impure set_<varname>(<initval>).
%
% Operations on mutables are defined in terms of the following two predicates.
+% They are actually "safe": we synchronize the access and assignment statements
+% within the predicates (by the Java specification, only actually necessary for
+% doubles and longs). They are named so to minimise the differences with the C
+% backends.
%
-% :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+% :- impure pred unsafe_set_<varname>(<vartype>::in(<varinst>)) is det.
% :- pragma foreign_proc("Java",
-% set_<varname>(X::in(<varinst>)),
+% unsafe_set_<varname>(X::in(<varinst>)),
% [will_not_call_mercury, thread_safe],
% "
% synchronized (mutable_<varname>_lock) {
@@ -245,9 +249,9 @@
% }
% ").
%
-% :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+% :- semipure pred unsafe_get_<varname>(<vartype>::out(<varinst>)) is det.
% :- pragma foreign_proc("Java",
-% get_varname(X::out(<varinst>)),
+% unsafe_get_varname(X::out(<varinst>)),
% [promise_semipure, will_not_call_mercury, thread_safe],
% "
% synchronized (mutable_<varname>_lock) {
@@ -255,6 +259,19 @@
% }
% ").
%
+% The above prediates are called by these predicates, again to minimise
+% differences with the C backends:
+%
+% :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+%
+% set_<varname>(X) :-
+% impure unsafe_set_<varname>(X).
+%
+% :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%
+% get_<varname>(X) :-
+% semipure unsafe_get_<varname>(X).
+%
% For constant mutables the transformation is:
%
% :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [constant]).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list