Fix callling a dynamic sub for object methods

7ec28f1a did not work with object
methods because we need a partial symbol table lookup to identify them,
otherwise the symbol kind we find is just SUB for the method's return
value.

Additions to the test case and vmod_debug by @slimhazard, thank you

Fixes #3521
parent d548292e
......@@ -192,3 +192,46 @@ logexpect l3 -wait
client c4 -wait
client c5 -wait
client c6 -wait
varnish v1 -vcl {
import debug;
backend b None;
sub foo {
set resp.http.Foo = "Called";
}
sub vcl_init {
new c = debug.caller(foo);
}
sub vcl_recv {
return (synth(200));
}
sub vcl_synth {
if (req.url == "/call") {
call c.xsub();
} else {
c.call();
}
return (deliver);
}
}
client c1 {
txreq -url "/call"
rxresp
expect resp.status == 200
expect resp.http.Foo == "Called"
} -start
client c2 {
txreq
rxresp
expect resp.status == 200
expect resp.http.Foo == "Called"
} -start
client c1 -wait
client c2 -wait
......@@ -50,8 +50,8 @@ vcc_act_call(struct vcc *tl, struct token *t, struct symbol *sym)
(void)t;
ExpectErr(tl, ID);
t0 = tl->t;
sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_REF);
sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL_NOERR,
XREF_REF);
if (sym == NULL)
sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_SUB, SYMTAB_CREATE,
XREF_REF);
......
......@@ -1331,3 +1331,62 @@ xyzzy_total_recall(VRT_CTX)
return (wrong);
}
/*---------------------------------------------------------------------*/
struct VPFX(debug_caller) {
unsigned magic;
#define DEBUG_CALLER_MAGIC 0xb47f3449
VCL_SUB sub;
};
VCL_VOID v_matchproto_(td_xyzzy_debug_caller__init)
xyzzy_caller__init(VRT_CTX, struct VPFX(debug_caller) **callerp,
const char *name, VCL_SUB sub)
{
struct VPFX(debug_caller) *caller;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(callerp);
AZ(*callerp);
AN(name);
AN(sub);
ALLOC_OBJ(caller, DEBUG_CALLER_MAGIC);
AN(caller);
*callerp = caller;
caller->sub = sub;
}
VCL_VOID v_matchproto_(td_xyzzy_debug_caller__fini)
xyzzy_caller__fini(struct VPFX(debug_caller) **callerp)
{
struct VPFX(debug_caller) *caller;
if (callerp == NULL || *callerp == NULL)
return;
CHECK_OBJ(*callerp, DEBUG_CALLER_MAGIC);
caller = *callerp;
*callerp = NULL;
FREE_OBJ(caller);
}
VCL_VOID v_matchproto_(td_xyzzy_debug_caller_call)
xyzzy_caller_call(VRT_CTX, struct VPFX(debug_caller) *caller)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(caller, DEBUG_CALLER_MAGIC);
AN(caller->sub);
VRT_call(ctx, caller->sub);
}
VCL_SUB v_matchproto_(td_xyzzy_debug_caller_sub)
xyzzy_caller_xsub(VRT_CTX, struct VPFX(debug_caller) *caller)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(caller, DEBUG_CALLER_MAGIC);
AN(caller->sub);
return (caller->sub);
}
......@@ -340,3 +340,9 @@ To test *WRONG* behavior
$Function SUB total_recall()
To test *WRONG* behavior
$Object caller(SUB)
$Method VOID .call()
$Method SUB .xsub()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment