示例#1
0
文件: gc.c 项目: neosam/moelisp
static void gc_traverse(pobject env)
{
    pobject object;
    while (is_cons(env)) {
        gc_flag_set(env, GC_FLAG_ON);
        object = cons_car(env);
        if (object && (gc_flag_get(object) == 0)) {
            /*
            printf("%p\n", object);
            */
            gc_flag_set(object, GC_FLAG_ON);

            /* XXX: dotted list support??? */
            if (is_cons(object)) {
                gc_traverse(object);
            } else if (is_closure(object)) {
                gc_traverse(object->data.closure.env);
                gc_traverse(object->data.closure.code);
            } else if (is_macro(object)) {
                gc_traverse(object->data.macro.env);
                gc_traverse(object->data.macro.code);
            }

        }
        env = cons_cdr(env);
    }
}
示例#2
0
文件: graph.cpp 项目: LLNL/lbann
bool is_topologically_sorted(const std::set<int>& nodes,
                             const std::map<int,std::set<int>>& edges) {
  if (!is_closure(nodes, edges)) {
    std::stringstream err;
    err << __FILE__ << " " << __LINE__ << " :: " << "graph is not a closure";
    throw lbann_exception(err.str());
  }
  for (const auto& node : nodes) {
    const auto& neighbors = get_neighbors(node, edges);
    if (neighbors.size() > 0 && *neighbors.begin() <= node) {
      return false;
    }
  }
  return true;
}
示例#3
0
文件: graph.cpp 项目: LLNL/lbann
std::map<int,std::set<int>> transpose(const std::set<int>& nodes,
                                      const std::map<int,std::set<int>>& edges) {
  if (!is_closure(nodes, edges)) {
    std::stringstream err;
    err << __FILE__ << " " << __LINE__ << " :: " << "graph is not a closure";
    throw lbann_exception(err.str());
  }
  std::map<int,std::set<int>> transpose_edges;
  for (const auto& node : nodes) {
    for (const auto& neighbor : get_neighbors(node, edges)) {
      transpose_edges[neighbor].insert(node);
    }
  }
  return transpose_edges;
}
示例#4
0
文件: graph.cpp 项目: LLNL/lbann
std::vector<int> topological_sort(const std::set<int>& nodes,
                                  const std::map<int,std::set<int>>& edges) {

  // Check that graph is valid
  if (!is_closure(nodes, edges)) {
    std::stringstream err;
    err << __FILE__ << " " << __LINE__ << " :: " << "graph is not a closure";
    throw lbann_exception(err.str());
  }
  if (is_cyclic(nodes, edges)) {
    std::stringstream err;
    err << __FILE__ << " " << __LINE__ << " :: " << "graph is cyclic";
    throw lbann_exception(err.str());
  }

  // Return original order if already sorted
  if (is_topologically_sorted(nodes, edges)) {
    return std::vector<int>(nodes.begin(), nodes.end());
  }

  // Perform depth-first searches on nodes
  std::stack<int> sorted_stack;
  std::unordered_map<int,bool> is_sorted;
  for (const auto& root : nodes) {
    if (!is_sorted[root]) {
      const auto& dfs = depth_first_search(root, edges);
      for (const auto& node : dfs) {
        if (!is_sorted[node]) {
          is_sorted[node] = true;
          sorted_stack.push(node);
        }
      }
    }
  }

  // Reverse DFS post-order is topologically sorted
  std::vector<int> sorted_nodes;
  while (!sorted_stack.empty()) {
    sorted_nodes.push_back(sorted_stack.top());
    sorted_stack.pop();
  }
  return sorted_nodes;
  
}
示例#5
0
文件: graph.cpp 项目: LLNL/lbann
bool is_cyclic(const std::set<int>& nodes,
               const std::map<int,std::set<int>>& edges) {

  // Check that graph is valid
  if (!is_closure(nodes, edges)) {
    std::stringstream err;
    err << __FILE__ << " " << __LINE__ << " :: " << "graph is not a closure";
    throw lbann_exception(err.str());
  }

  // Topologically sorted graphs are not cyclic
  if (is_topologically_sorted(nodes, edges)) {
    return false;
  }

  // Perform depth-first searches to detect cycles
  std::unordered_map<int,bool> is_visited, is_sorted;
  std::stack<int> search_stack;
  for (auto&& it = nodes.rbegin(); it != nodes.rend(); ++it) {
    search_stack.push(*it);
  }
  while (!search_stack.empty()) {
    const auto& node = search_stack.top();
    search_stack.pop();
    if (!is_sorted[node]) {
      if (is_visited[node]) {
        is_sorted[node] = true;
      } else {
        is_visited[node] = true;
        search_stack.push(node);
        for (const auto& neighbor : get_neighbors(node, edges)) {
          if (is_visited[neighbor] && !is_sorted[neighbor]) {
            return true;
          }
          search_stack.push(neighbor);
        }
      }
    }
  }
  return false;
  
}
示例#6
0
文件: check.cpp 项目: DerPapst/hhvm
bool check(const php::Class& c) {
  assert(checkName(c.name));
  for (DEBUG_ONLY auto& m : c.methods) assert(check(*m));

  // Some invariants about Closure classes.
  auto const isClo = is_closure(c);
  if (c.closureContextCls) {
    assert(c.closureContextCls->unit == c.unit);
    assert(isClo);
  }
  if (isClo) {
    assert(c.methods.size() == 1);
    assert(c.methods[0]->name->isame(s_invoke.get()));
    assert(c.methods[0]->isClosureBody);
  } else {
    assert(!c.closureContextCls);
  }

  return true;
}
std::string
TypeSpec::string () const
{
    std::string str;
    if (is_closure() || is_closure_array()) {
        str += "closure color";
        if (is_unsized_array())
            str += "[]";
        else if (arraylength() > 0)
            str += Strutil::format ("[%d]", arraylength());
    }
    else if (structure() > 0) {
        str += Strutil::format ("struct %d", structure());
        if (is_unsized_array())
            str += "[]";
        else if (arraylength() > 0)
            str += Strutil::format ("[%d]", arraylength());
    } else {
        str += simpletype().c_str();
    }
    return str;
}
示例#8
0
文件: emit.cpp 项目: nadanomics/hhvm
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);
  pce->setNumDeclMethods(cls.numDeclMethods);

  pce->setIfaceVtableSlot(state.index.lookup_iface_vtable_slot(&cls));

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const makeRat = [&] (const Type& ty) -> RepoAuthType {
      if (ty.couldBe(TCls)) {
        return RepoAuthType{};
      }
      auto const rat = make_repo_type(*state.index.array_table_builder(), ty);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    auto const privPropTy = [&] (const PropState& ps) -> Type {
      /*
       * Skip closures, because the types of their used vars can be
       * communicated via assert opcodes right now.  At the time of this
       * writing there was nothing to gain by including RAT's for the
       * properties, since closure properties are only used internally by the
       * runtime, not directly via opcodes like CGetM.
       */
      if (is_closure(cls)) return Type{};

      auto it = ps.find(prop.name);
      if (it == end(ps)) return Type{};
      return it->second;
    };

    Type propTy;
    auto const attrs = prop.attrs;
    if (attrs & AttrPrivate) {
      propTy = privPropTy((attrs & AttrStatic) ? privateStatics : privateProps);
    } else if ((attrs & AttrPublic) && (attrs & AttrStatic)) {
      propTy = state.index.lookup_public_static(&cls, prop.name);
    }

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      makeRat(propTy)
    );
  }

  for (auto& cconst : cls.constants) {
    if (!cconst.val.hasValue()) {
      pce->addAbstractConstant(
        cconst.name,
        cconst.typeConstraint,
        cconst.isTypeconst
      );
    } else {
      pce->addConstant(
        cconst.name,
        cconst.typeConstraint,
        &cconst.val.value(),
        cconst.phpCode,
        cconst.isTypeconst
      );
    }
  }

  pce->setEnumBaseTy(cls.enumBaseTy);
}
示例#9
0
文件: emit.cpp 项目: ashishbeg/hhvm
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);
  pce->setNumDeclMethods(cls.numDeclMethods);

  pce->setIfaceVtableSlot(state.index.lookup_iface_vtable_slot(&cls));

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  std::vector<Type> useVars;
  if (is_closure(cls)) {
    auto f = find_method(&cls, s_invoke.get());
    useVars = state.index.lookup_closure_use_vars(f);
  }
  auto uvIt = useVars.begin();

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const makeRat = [&] (const Type& ty) -> RepoAuthType {
      if (ty.couldBe(TCls)) {
        return RepoAuthType{};
      }
      auto const rat = make_repo_type(*state.index.array_table_builder(), ty);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    auto const privPropTy = [&] (const PropState& ps) -> Type {
      if (is_closure(cls)) {
        // For closures use variables will be the first properties of the
        // closure object, in declaration order
        if (uvIt != useVars.end()) return *uvIt++;
        return Type{};
      }

      auto it = ps.find(prop.name);
      if (it == end(ps)) return Type{};
      return it->second;
    };

    Type propTy;
    auto const attrs = prop.attrs;
    if (attrs & AttrPrivate) {
      propTy = privPropTy((attrs & AttrStatic) ? privateStatics : privateProps);
    } else if ((attrs & AttrPublic) && (attrs & AttrStatic)) {
      propTy = state.index.lookup_public_static(&cls, prop.name);
    }

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      makeRat(propTy)
    );
  }
  assert(uvIt == useVars.end());

  for (auto& cconst : cls.constants) {
    if (!cconst.val.hasValue()) {
      pce->addAbstractConstant(
        cconst.name,
        cconst.typeConstraint,
        cconst.isTypeconst
      );
    } else {
      pce->addConstant(
        cconst.name,
        cconst.typeConstraint,
        &cconst.val.value(),
        cconst.phpCode,
        cconst.isTypeconst
      );
    }
  }

  pce->setEnumBaseTy(cls.enumBaseTy);
}
示例#10
0
文件: emit.cpp 项目: brucezy/hhvm
void emit_class(EmitUnitState& state,
                UnitEmitter& ue,
                const php::Class& cls) {
  FTRACE(2, "    class: {}\n", cls.name->data());
  auto const pce = ue.newPreClassEmitter(
    cls.name,
    cls.hoistability
  );
  pce->init(
    std::get<0>(cls.srcInfo.loc),
    std::get<1>(cls.srcInfo.loc),
    ue.bcPos(),
    cls.attrs,
    cls.parentName ? cls.parentName : s_empty.get(),
    cls.srcInfo.docComment
  );
  pce->setUserAttributes(cls.userAttributes);

  for (auto& x : cls.interfaceNames)     pce->addInterface(x);
  for (auto& x : cls.usedTraitNames)     pce->addUsedTrait(x);
  for (auto& x : cls.requirements)       pce->addClassRequirement(x);
  for (auto& x : cls.traitPrecRules)     pce->addTraitPrecRule(x);
  for (auto& x : cls.traitAliasRules)    pce->addTraitAliasRule(x);

  for (auto& m : cls.methods) {
    FTRACE(2, "    method: {}\n", m->name->data());
    auto const fe = ue.newMethodEmitter(m->name, pce);
    emit_init_func(*fe, *m);
    pce->addMethod(fe);
    auto const info = emit_bytecode(state, ue, *m);
    emit_finish_func(*m, *fe, info);
  }

  auto const privateProps   = state.index.lookup_private_props(&cls);
  auto const privateStatics = state.index.lookup_private_statics(&cls);
  for (auto& prop : cls.properties) {
    auto const repoTy = [&] (const PropState& ps) -> RepoAuthType {
      // TODO(#3599292): we don't currently infer closure use var types.
      if (is_closure(cls)) return RepoAuthType{};
      auto it = ps.find(prop.name);
      if (it == end(ps)) return RepoAuthType{};
      auto const rat = make_repo_type(*state.index.array_table_builder(),
                                      it->second);
      merge_repo_auth_type(ue, rat);
      return rat;
    };

    pce->addProperty(
      prop.name,
      prop.attrs,
      prop.typeConstraint,
      prop.docComment,
      &prop.val,
      (prop.attrs & AttrStatic) ? repoTy(privateStatics) : repoTy(privateProps)
    );
  }

  for (auto& cconst : cls.constants) {
    pce->addConstant(
      cconst.name,
      cconst.typeConstraint,
      &cconst.val,
      cconst.phpCode
    );
  }
}