fuzion
fuzion copied to clipboard
In C backend, illegal access to mutable var is not detected
This example
m : mutate is
s := m.go (() -> m.env.new 0)
_ := s.get
say "*** failed, should have panicked ***"
correctly panics using the JVM backend
> ../../bin/fz test_local_mutate.fz
*** panic: *** invalid mutate for Type of 'm'
But does not with the C backend
> ../../bin/fz -c test_local_mutate.fz && ./universe
*** failed, should have panicked ***
Problem is that getEffectForce for effect clazz m returns null which is then pushed to stack, stopping further interpretation.
// code for clazz#10639 m.type.unsafe_get:
fzT_m fzC_m_oHtype_w_m__unsafe_u_get()
{
start:
{
// cur does not escape, alloc on stack
fzT_m_oHtype_w_m__unsafe_u_get fzCur;
memset(&fzCur,0,sizeof fzCur);
// 805306709: Env
if (!fzThrd_effectsEnvironment->fzEnvInstalled_11572)
{
fprintf(stderr,"*** effect %s not present in current environment\012","m");
exit(1);
}
// 805306710: Box m => m
// Box is a NOP, clazz is already a ref
// 805306711: Current
// 805306712: Assign to m.type.unsafe_get.#result
// access to Assign to m.type.unsafe_get.#result eliminated
return fzCur.fzF_0__Hresult;
}
}
and then here the tagging code is missing since unsafe_get is wrongly considered to always result in void:
// code for clazz#10619 m.type.get_if_installed:
fzT_option_w_m fzC__L10619m_oHtype_w__nstalled()
{
start:
{
// cur does not escape, alloc on stack
fzT__L10619m_oHtype_w__nstalled fzCur;
memset(&fzCur,0,sizeof fzCur);
// 805306698: Current
// 805306699: Call m.type.get_if_installed.#^effect.type.get_if_installed(outer m.type.get_if_installed) m.type
// access to Call m.type.get_if_installed.#^effect.type.get_if_installed(outer m.type.get_if_installed) m.type eliminated
// 805306700: Call m.type.is_installed#1 m(outer m.type) bool
fzT_bool fzM_0;
fzM_0 = fzC__L10609m_oHtype_w__lled_w_m();
// 805306701: Match 0=>l318 1=>l325
switch (fzM_0.fzTag)
{
case 1/* TRUE */:
{
// 805306686: Current
// 805306687: Call m.type.get_if_installed.#^effect.type.get_if_installed(outer m.type.get_if_installed) m.type
// access to Call m.type.get_if_installed.#^effect.type.get_if_installed(outer m.type.get_if_installed) m.type eliminated
// 805306688: Call m.type.unsafe_get(outer m.type) m
fzT_m fzM_1;
fzM_1 = fzC_m_oHtype_w_m__unsafe_u_get();
break;
}
case 0/* FALSE */:
{
// 805306693: Call nil(outer universe) nil
fzC_nil();
// 805306694: Tag
// Tag a value to be of choice type option m static value type nil
fzT_option_w_m fzM_2;
fzM_2.fzTag = 1;
// unit type assignment to fzM_2.fzChoice.v1
// 805306695: Current
// 805306696: Assign to m.type.get_if_installed.#exprResult1102
fzCur.fzF_2__HexprResult1102 = fzM_2;
break;
}
}
// 805306704: Current
// 805306705: Call m.type.get_if_installed.#exprResult1102(outer m.type.get_if_installed) option m
// 805306706: Current
// 805306707: Assign to m.type.get_if_installed.#result
fzCur.fzF_0__Hresult = fzCur.fzF_2__HexprResult1102;
return fzCur.fzF_0__Hresult;
}
}
So the jvm backend works by chance only.