bool Emitter::process_jit_candidates(const std::vector<Term *> &asts) { std::deque<Term *> queue(asts.begin(), asts.end()); error_message.clear(); while (queue.size()) { Term *ast = queue.front(); queue.pop_front(); switch (ast->get_type()) { case pj_ttype_lexical: case pj_ttype_variabledeclaration: case pj_ttype_global: case pj_ttype_constant: continue; case pj_ttype_statementsequence: { const std::vector<Term *> &kids = ast->get_kids(); std::vector<Term *> seq; for (size_t i = 0, max = kids.size(); i < max; ++i) { Term *stmt = kids[i]; if (is_jittable(stmt)) { seq.push_back(static_cast<Statement *>(stmt)); } else { if (seq.size()) { if (!jit_statement_sequence(seq)) return false; seq.clear(); } if (!process_jit_candidates(stmt->get_kids())) return false; } } if (seq.size()) if (!jit_statement_sequence(seq)) return false; break; } default: if (is_jittable(ast)) { jit_tree(ast); } else { const std::vector<Term *> &kids = ast->get_kids(); queue.insert(queue.begin(), kids.begin(), kids.end()); } break; } } return true; }
bool Emitter::needs_excessive_magic(PerlJIT::AST::Op *ast) { std::deque<Term *> nodes(1, ast); while (nodes.size()) { Term *node = nodes.front(); nodes.pop_front(); if ((node->get_type() == pj_ttype_lexical || node->get_type() == pj_ttype_variabledeclaration) && node->get_value_type()->is_opaque()) return true; if (node->get_type() != pj_ttype_op) continue; Op *op = static_cast<Op *>(node); bool known = Jittable_Ops.find(op->get_op_type()) != Jittable_Ops.end(); if (!known || !op->may_have_explicit_overload()) continue; std::vector<Term *> kids = node->get_kids(); nodes.insert(nodes.end(), kids.begin(), kids.end()); } return false; }