Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}