summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2007-10-03 20:34:43 +0000
committerfche <fche>2007-10-03 20:34:43 +0000
commit60ba482cc7455d45a9ce5b6f6021a0ccdc3ee70b (patch)
tree3481639c59f695c2ca74495ee09865d7acbeca51
parent683b62c034369da0778dbfe557f44a2ca73f76d4 (diff)
downloadsystemtap-steved-60ba482cc7455d45a9ce5b6f6021a0ccdc3ee70b.tar.gz
systemtap-steved-60ba482cc7455d45a9ce5b6f6021a0ccdc3ee70b.tar.xz
systemtap-steved-60ba482cc7455d45a9ce5b6f6021a0ccdc3ee70b.zip
PR 5096: improve code generation for function calls
2007-10-03 Frank Ch. Eigler <fche@elastic.org> PR 5096 * translate.cxx (emit_function): Put nesting limit/control logic into function body ... (visit_functioncall): ... and not into each call site.
-rw-r--r--ChangeLog7
-rw-r--r--translate.cxx37
2 files changed, 26 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 26a55d74..4142933c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-10-03 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 5096
+ * translate.cxx (emit_function): Put nesting limit/control logic into
+ function body ...
+ (visit_functioncall): ... and not into each call site.
+
2007-10-02 Frank Ch. Eigler <fche@redhat.com>
PR 3635
diff --git a/translate.cxx b/translate.cxx
index 8e24fca0..578bbc37 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1333,13 +1333,21 @@ c_unparser::emit_function (functiondecl* v)
<< "struct function_" << c_varname (v->name) << "_locals * "
<< " __restrict__ l =";
o->newline(1)
- << "& c->locals[c->nesting].function_" << c_varname (v->name)
+ << "& c->locals[c->nesting+1].function_" << c_varname (v->name) // NB: nesting+1
<< ";";
o->newline(-1) << "(void) l;"; // make sure "l" is marked used
o->newline() << "#define CONTEXT c";
o->newline() << "#define THIS l";
o->newline() << "if (0) goto out;"; // make sure out: is marked used
+ // check/increment nesting level
+ o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {";
+ o->newline(1) << "c->last_error = \"MAXNESTING exceeded\";";
+ o->newline() << "return;";
+ o->newline(-1) << "} else {";
+ o->newline(1) << "c->nesting ++;";
+ o->newline(-1) << "}";
+
// initialize locals
// XXX: optimization: use memset instead
for (unsigned i=0; i<v->locals.size(); i++)
@@ -1358,13 +1366,23 @@ c_unparser::emit_function (functiondecl* v)
o->newline() << retvalue.init();
}
+ o->newline() << "#define return goto out"; // redirect embedded-C return
v->body->visit (this);
+ o->newline() << "#undef return";
this->current_function = 0;
o->newline(-1) << "out:";
o->newline(1) << ";";
+ // Function prologue: this is why we redirect the "return" above.
+ // Decrement nesting level.
+ o->newline() << "c->nesting --;";
+ // Reset last_error to NULL if it was set to "" by script-level return()
+ o->newline() << "if (c->last_error && ! c->last_error[0])";
+ o->newline(1) << "c->last_error = 0;";
+ o->indent(-1);
+
o->newline() << "#undef CONTEXT";
o->newline() << "#undef THIS";
o->newline(-1) << "}\n";
@@ -3878,13 +3896,6 @@ c_unparser::visit_functioncall (functioncall* e)
tmp.push_back(t);
}
- o->newline();
- o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {";
- o->newline(1) << "c->last_error = \"MAXNESTING exceeded\";";
- o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
- o->newline(-1) << "} else if (likely (! c->last_error)) {";
- o->indent(1);
-
// copy in actual arguments
for (unsigned i=0; i<e->args.size(); i++)
{
@@ -3902,19 +3913,9 @@ c_unparser::visit_functioncall (functioncall* e)
}
// call function
- o->newline() << "c->nesting ++;";
o->newline() << "function_" << c_varname (r->name) << " (c);";
- o->newline() << "c->nesting --;";
-
- // reset last_error to NULL if it was set to "" by return()
- o->newline() << "if (c->last_error && ! c->last_error[0])";
- o->newline(1) << "c->last_error = 0;";
- o->indent(-1);
-
- o->newline(-1) << "}";
// return result from retvalue slot
-
if (r->type == pe_unknown)
// If we passed typechecking, then nothing will use this return value
o->newline() << "(void) 0;";