From 4993ac3ad50b1b937924c6aba9ea9a28fc46dddf Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 10 Aug 2022 22:49:59 +0100 Subject: [PATCH] Refactor lower_context_for_call. Issue #502 --- NEWS.md | 1 + src/jit/jit-interp.c | 1 + src/lower.c | 105 +++++++++++++++++++++++--------------- test/regress/issue502.vhd | 48 +++++++++++++++++ test/regress/testlist.txt | 1 + 5 files changed, 116 insertions(+), 40 deletions(-) create mode 100644 test/regress/issue502.vhd diff --git a/NEWS.md b/NEWS.md index 05edec91..c74bdc7d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ ## Unreleased changes - Added missing textio `WRITE [LINE, REAL, STRING]` in VHDL-2008. - Added support for FreeBSD/powerpc (#503, #504, from @pkubaj). +- Fixed "missing vcode unit" error during elaboration (#502). ## Version 1.7.0 - 2022-08-07 diff --git a/src/jit/jit-interp.c b/src/jit/jit-interp.c index 84a45e58..443490d7 100644 --- a/src/jit/jit-interp.c +++ b/src/jit/jit-interp.c @@ -485,6 +485,7 @@ static void interp_uload(jit_interp_t *state, jit_ir_t *ir) JIT_ASSERT(ir->size != JIT_SZ_UNSPEC); JIT_ASSERT(arg1.pointer != NULL); + JIT_ASSERT((uintptr_t)arg1.pointer >= 4096); switch (ir->size) { case JIT_SZ_8: diff --git a/src/lower.c b/src/lower.c index 0322041a..69a6a2b4 100644 --- a/src/lower.c +++ b/src/lower.c @@ -1977,67 +1977,92 @@ static vcode_cc_t lower_cc_for_call(tree_t call) static vcode_reg_t lower_context_for_call(ident_t unit_name) { - ident_t scope_name = ident_runtil(ident_runtil(unit_name, '('), '.'); - - if (vcode_unit_kind() == VCODE_UNIT_THUNK) { - // This is a hack to make thunks work - tree_t pack = lib_get_qualified(scope_name); - if (pack != NULL && is_package(pack)) { - assert(!is_uninstantiated_package(pack)); - return emit_package_init(scope_name, VCODE_INVALID_REG); - } - } + vcode_unit_t caller = vcode_active_unit(); vcode_state_t state; vcode_state_save(&state); vcode_unit_t vu = vcode_find_unit(unit_name); + + if (vu == NULL && vcode_unit_kind() == VCODE_UNIT_THUNK) { + ident_t thunk_name = ident_prefix(unit_name, well_known(W_THUNK), '$'); + vu = vcode_find_unit(thunk_name); + } + if (vu != NULL) { vcode_select_unit(vu); - vcode_select_unit(vcode_unit_context()); - scope_name = vcode_unit_name(); - } + vcode_unit_t context = vcode_unit_context(); - if (vcode_unit_kind() == VCODE_UNIT_THUNK) { - unit_name = ident_prefix(unit_name, well_known(W_THUNK), '$'); - vu = vcode_find_unit(unit_name); - if (vu != NULL) { - vcode_select_unit(vu); - if (vcode_unit_context() != NULL) { - vcode_select_unit(vcode_unit_context()); - scope_name = vcode_unit_name(); + if (context == caller) { + vcode_state_restore(&state); + return emit_context_upref(0); + } + else if (context == NULL) { + assert(vcode_unit_kind() == VCODE_UNIT_THUNK); + vcode_state_restore(&state); + return emit_null(vtype_context(unit_name)); + } + + vcode_select_unit(context); + + ident_t context_name = vcode_unit_name(); + vunit_kind_t context_kind = vcode_unit_kind(); + vcode_state_restore(&state); + + if (context_kind == VCODE_UNIT_PACKAGE) { + if (vcode_unit_kind() == VCODE_UNIT_THUNK) + return emit_package_init(context_name, VCODE_INVALID_REG); + else if (context == vcode_unit_context()) + return emit_context_upref(1); + else + return emit_link_package(context_name); + } + else { + int hops = 0; + for (; vcode_active_unit() != context; hops++) { + vcode_unit_t up = vcode_unit_context(); + if (up == NULL) { + vcode_state_restore(&state); + return emit_null(vtype_context(context_name)); + } + + vcode_select_unit(up); } + + vcode_state_restore(&state); + return emit_context_upref(hops); } } vcode_state_restore(&state); int hops = 0; - for (; vcode_unit_name() != scope_name; hops++) { - vcode_unit_t context = vcode_unit_context(); - if (context == NULL) { + for (; ; hops++) { + if (ident_starts_with(unit_name, vcode_unit_name())) { vcode_state_restore(&state); - if (ident_until(scope_name, '-') != scope_name - || ident_until(unit_name, '-') != unit_name - || vcode_unit_kind() == VCODE_UNIT_THUNK) { - tree_t pack = lib_get_qualified(scope_name); - if (pack != NULL && is_package(pack)) { - assert(!is_uninstantiated_package(pack)); - return emit_link_package(scope_name); - } - else // Call to function defined in architecture - return emit_null(vtype_context(scope_name)); - } - else - return emit_link_package(scope_name); + return emit_context_upref(hops); } - else - vcode_select_unit(context); + + vcode_unit_t context = vcode_unit_context(); + if (context == NULL) + break; + + vcode_select_unit(context); } vcode_state_restore(&state); - return emit_context_upref(hops); + ident_t scope_name = ident_runtil(ident_until(unit_name, '('), '.'); + tree_t pack = lib_get_qualified(scope_name); + if (pack != NULL && is_package(pack)) { + assert(!is_uninstantiated_package(pack)); + if (vcode_unit_kind() == VCODE_UNIT_THUNK) + return emit_package_init(scope_name, VCODE_INVALID_REG); + else + return emit_link_package(scope_name); + } + else // Call to function defined in architecture + return emit_null(vtype_context(scope_name)); } static vcode_reg_t lower_fcall(tree_t fcall, expr_ctx_t ctx) diff --git a/test/regress/issue502.vhd b/test/regress/issue502.vhd new file mode 100644 index 00000000..f2d1d629 --- /dev/null +++ b/test/regress/issue502.vhd @@ -0,0 +1,48 @@ +entity sub is + generic ( n : integer); +end entity; + +architecture test of sub is + type rec is record + f : integer range 1 to n; + end record; + + function func1 (x : integer) return rec; + + function func2 (x : integer) return rec is + begin + return func1(x); + end function; + + function func1 (x : integer) return rec is + begin + return (f => x * 2); + end function; + + signal s, t : integer := 0; +begin + + p1: t <= func2(s).f; + + p2: process is + begin + wait; + end process; + +end architecture; + +------------------------------------------------------------------------------- + +entity issue502 is +end entity; + +architecture test of issue502 is +begin + + g: for i in 1 to 3 generate + begin + u: entity work.sub + generic map ( i ); + end generate; + +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 590f85f5..f9db91ac 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -641,3 +641,4 @@ wait24 normal agg9 normal agg10 normal,2008 signal26 normal,2008 +issue502 normal -- 2.39.2