Пример #1
0
std::string Array::to_string() const {
  if (is_primitive()) {
    return "< " + element_type->to_string() + " x " + std::to_string(length) + " >";
  } else {
    return "[ " + element_type->to_string() + " x " + std::to_string(length) + " ]";
  }
}
Пример #2
0
void remove_unused_fields(Scope& scope,
    const std::vector<std::string>& remove_members) {
  std::vector<DexField*> moveable_fields;
  std::vector<DexClass*> smallscope;
  uint32_t aflags = ACC_STATIC | ACC_FINAL;
  for (auto clazz : scope) {
    bool found = can_delete(clazz);
    if (!found) {
      auto name = clazz->get_name()->c_str();
      for (const auto& name_prefix : remove_members) {
        if (strstr(name, name_prefix.c_str()) != nullptr) {
          found = true;
          break;
        }
      }
      if (!found) {
        TRACE(FINALINLINE, 2, "Cannot delete: %s\n", SHOW(clazz));
        continue;
      }
    }
    auto sfields = clazz->get_sfields();
    for (auto sfield : sfields) {
      if ((sfield->get_access() & aflags) != aflags) continue;
      auto value = sfield->get_static_value();
      if (value == nullptr && !is_primitive(sfield->get_type())) continue;
      if (!found && !can_delete(sfield)) continue;

      moveable_fields.push_back(sfield);
      smallscope.push_back(clazz);
    }
  }
  sort_unique(smallscope);

  std::unordered_set<DexField*> field_target =
      get_field_target(scope, moveable_fields);
  std::unordered_set<DexField*> dead_fields;
  for (auto field : moveable_fields) {
    if (field_target.count(field) == 0) {
      dead_fields.insert(field);
    }
  }
  TRACE(FINALINLINE, 1,
          "Removable fields %lu/%lu\n",
          dead_fields.size(),
          moveable_fields.size());
  TRACE(FINALINLINE, 1, "Unhandled inline %ld\n", unhandled_inline);

  for (auto clazz : smallscope) {
    auto& sfields = clazz->get_sfields();
    auto iter = sfields.begin();
    while (iter != sfields.end()) {
      auto todel = iter++;
      if (dead_fields.count(*todel) > 0) {
        sfields.erase(todel);
      }
    }
  }
}
Пример #3
0
void inline_field_values(Scope& fullscope) {
  std::unordered_set<DexField*> inline_field;
  std::unordered_set<DexField*> cheap_inline_field;
  std::vector<DexClass*> scope;
  uint32_t aflags = ACC_STATIC | ACC_FINAL;

  for (auto clazz : fullscope) {
    std::unordered_map<DexField*, bool> blank_statics;
    get_sput_in_clinit(clazz, blank_statics);
    auto sfields = clazz->get_sfields();
    for (auto sfield : sfields) {
      if ((sfield->get_access() & aflags) != aflags) continue;
      if (blank_statics[sfield]) continue;
      auto value = sfield->get_static_value();
      if (value == nullptr && !is_primitive(sfield->get_type())) {
        continue;
      }
      if (value != nullptr && !value->is_evtype_primitive()) {
        continue;
      }
      uint64_t v = value != nullptr ? value->value() : 0;
      if ((v & 0xffff) == v || (v & 0xffff0000) == v) {
        cheap_inline_field.insert(sfield);
      }
      inline_field.insert(sfield);
      scope.push_back(clazz);
    }
  }
  std::vector<std::pair<DexMethod*, DexOpcodeField*>> cheap_rewrites;
  std::vector<std::pair<DexMethod*, DexOpcodeField*>> simple_rewrites;
  walk_opcodes(
      fullscope,
      [](DexMethod* method) { return true; },
      [&](DexMethod* method, DexInstruction* insn) {
        if (insn->has_fields() && is_sfield_op(insn->opcode())) {
          auto fieldop = static_cast<DexOpcodeField*>(insn);
          auto field = resolve_field(fieldop->field(), FieldSearch::Static);
          if (field == nullptr || !field->is_concrete()) return;
          if (inline_field.count(field) == 0) return;
          if (cheap_inline_field.count(field) > 0) {
            cheap_rewrites.push_back(std::make_pair(method, fieldop));
            return;
          }
          simple_rewrites.push_back(std::make_pair(method, fieldop));
        }
      });
  TRACE(FINALINLINE, 1,
          "Method Re-writes Cheap %lu  Simple %lu\n",
          cheap_rewrites.size(),
          simple_rewrites.size());
  for (auto cheapcase : cheap_rewrites) {
    inline_cheap_sget(cheapcase.first, cheapcase.second);
  }
  for (auto simplecase : simple_rewrites) {
    inline_sget(simplecase.first, simplecase.second);
  }
  MethodTransform::sync_all();
}
Пример #4
0
PyObject* JPypeJavaArray::setArraySlice(PyObject* self, PyObject* arg)
{
	TRACE_IN("JPypeJavaArray::setArraySlice")
	PyObject* arrayObject;
	int lo = -1;
	int hi = -1;
	PyObject* sequence;
	try {
		JPyArg::parseTuple(arg, "O!iiO", &PyCapsule_Type, &arrayObject, &lo, &hi, &sequence);
		JPArray* a = (JPArray*)JPyCObject::asVoidPtr(arrayObject);

		int length = a->getLength();
		if(length == 0)
			Py_RETURN_NONE;

		if (lo < 0) lo = length + lo;
		if (lo < 0) lo = 0;
		else if (lo > length) lo = length;
		if (hi < 0) hi = length + hi;
		if (hi < 0) hi = 0;
		else if (hi > length) hi = length;
		if (lo > hi) lo = hi;

		const JPTypeName& componentName = a->getType()->getObjectType().getComponentName();
		const string& name = componentName.getNativeName();

		if(is_primitive(name[0]))
		{
			// for primitive types, we have fast setters available
			a->setRange(lo, hi, sequence);
		}
		else
		{
			// slow wrapped access for non primitive types
			vector<HostRef*> values;
			values.reserve(hi - lo);
			JPCleaner cleaner;
			for (Py_ssize_t i = 0; i < hi - lo; i++)
			{
				HostRef* v = new HostRef(JPySequence::getItem(sequence, i), false);
				values.push_back(v);
				cleaner.add(v);
			}

			a->setRange(lo, hi, values);
		}

		Py_RETURN_NONE;
	}
	PY_STANDARD_CATCH

	return NULL;
	TRACE_OUT
}
Пример #5
0
sexp eval_application(sexp operator, sexp operands) {
  if (is_primitive(operator))
    return (primitive_C_proc(operator))(operands);
  if (is_compound(operator)) {
    sexp body = compound_proc_body(operator);
    sexp vars = compound_proc_parameters(operator);
    sexp def_env = compound_proc_environment(operator);
    sexp object = make_pair(S("begin"), body);
    sexp env = extend_environment(vars, operands, def_env);
    return eval_object(object, env);
  }
  fprintf(stderr, "Unknown operator type %d\n", operator->type);
  exit(1);
}
Пример #6
0
void remove_unused_fields(Scope& scope,
                          const std::unordered_set<DexType*>& keep_annos,
                          const std::unordered_set<DexField*>& keep_members) {
  std::vector<DexField*> moveable_fields;
  std::vector<DexClass*> smallscope;
  uint32_t aflags = ACC_STATIC | ACC_FINAL;
  for (auto clazz : scope) {
    if (!can_delete(clazz)) {
      continue;
    }
    auto sfields = clazz->get_sfields();
    for (auto sfield : sfields) {
      if ((sfield->get_access() & aflags) != aflags) continue;
      auto value = sfield->get_static_value();
      if (value == nullptr && !is_primitive(sfield->get_type())) continue;
      if (is_kept_by_annotation(sfield, keep_annos)) continue;
      if (is_kept_member(sfield, keep_members)) continue;

      moveable_fields.push_back(sfield);
      smallscope.push_back(clazz);
    }
  }
  sort_unique(smallscope);

  std::unordered_set<DexField*> field_target =
      get_field_target(scope, moveable_fields);
  std::unordered_set<DexField*> dead_fields;
  for (auto field : moveable_fields) {
    if (field_target.count(field) == 0) {
      dead_fields.insert(field);
    }
  }
  TRACE(FINALINLINE, 1,
          "Removable fields %lu/%lu\n",
          dead_fields.size(),
          moveable_fields.size());
  TRACE(FINALINLINE, 1, "Unhandled inline %ld\n", unhandled_inline);

  for (auto clazz : smallscope) {
    auto& sfields = clazz->get_sfields();
    auto iter = sfields.begin();
    while (iter != sfields.end()) {
      auto todel = iter++;
      if (dead_fields.count(*todel) > 0) {
        sfields.erase(todel);
      }
    }
  }
}
Пример #7
0
/*
 * This returns all the pointer-bearing registers whose pointees :insn will
 * read from.
 */
std::vector<uint16_t> object_read_registers(const IRInstruction* insn) {
  switch (insn->opcode()) {
  case OPCODE_AGET:
  case OPCODE_AGET_WIDE:
  case OPCODE_AGET_BOOLEAN:
  case OPCODE_AGET_BYTE:
  case OPCODE_AGET_CHAR:
  case OPCODE_AGET_SHORT:
  case OPCODE_AGET_OBJECT:
  case OPCODE_IGET:
  case OPCODE_IGET_WIDE:
  case OPCODE_IGET_BOOLEAN:
  case OPCODE_IGET_BYTE:
  case OPCODE_IGET_CHAR:
  case OPCODE_IGET_SHORT:
  case OPCODE_IGET_OBJECT:

  case OPCODE_APUT_OBJECT:
  case OPCODE_IPUT_OBJECT:
  case OPCODE_SPUT_OBJECT:

  case OPCODE_RETURN_OBJECT:
    return {insn->src(0)};

  case OPCODE_INVOKE_SUPER:
  case OPCODE_INVOKE_DIRECT:
  case OPCODE_INVOKE_STATIC:
  case OPCODE_INVOKE_VIRTUAL:
  case OPCODE_INVOKE_INTERFACE: {
    std::vector<uint16_t> regs;
    size_t idx{0};
    if (insn->opcode() != OPCODE_INVOKE_STATIC) {
      // The `this` parameter
      regs.emplace_back(insn->src(idx++));
    }
    auto callee = insn->get_method();
    auto arg_types = callee->get_proto()->get_args()->get_type_list();
    for (DexType* arg_type : arg_types) {
      if (!is_primitive(arg_type)) {
        regs.emplace_back(insn->src(idx));
      }
      ++idx;
    }
    return regs;
  }
  default:
    return {};
  }
}
Пример #8
0
PyObject* JPypeJavaArray::getArraySlice(PyObject* self, PyObject* arg)
{
	PyObject* arrayObject;
	int lo = -1;
	int hi = -1;
	try
	{

		JPyArg::parseTuple(arg, "O!ii", &PyCapsule_Type, &arrayObject, &lo, &hi);
		JPArray* a = (JPArray*)JPyCObject::asVoidPtr(arrayObject);
		int length = a->getLength();
		// stolen from jcc, to get nice slice support
		if (lo < 0) lo = length + lo;
		if (lo < 0) lo = 0;
		else if (lo > length) lo = length;
		if (hi < 0) hi = length + hi;
		if (hi < 0) hi = 0;
		else if (hi > length) hi = length;
		if (lo > hi) lo = hi;

		const JPTypeName& componentName = a->getType()->getObjectType().getComponentName();
		const string& name = componentName.getNativeName();
		if(is_primitive(name[0]))
		{
			// for primitive types, we have fast sequence generation available
			return a->getSequenceFromRange(lo, hi);
		}
		else
		{
			// slow wrapped access for non primitives
			vector<HostRef*> values = a->getRange(lo, hi);

			JPCleaner cleaner;
			PyObject* res = JPySequence::newList((int)values.size());
			for (unsigned int i = 0; i < values.size(); i++)
			{
				JPySequence::setItem(res, i, (PyObject*)values[i]->data());
				cleaner.add(values[i]);
			}

			return res;
		}
	} PY_STANDARD_CATCH

	return NULL;
}
Пример #9
0
Type Type::operator * (const Type& t2) const {
	if (_types.size() == 0) {
		return t2;
	}
	if (t2._types.size() == 0) {
		return *this;
	}
	if (*this == t2) {
		return *this;
	}
	if (is_polymorphic() and t2.is_primitive()) {
		return Type::any();
	}
	if (t2.is_polymorphic() and is_primitive()) {
		return Type::any();
	}
	if (is_any()) {
		return t2;
	}
	if (t2.is_any()) {
		return *this;
	}
	// Temporary, to be removed when compatible() is removed
	if ((is_bool() and t2.is_integer()) or (is_integer() and t2.is_bool())) {
		return any();
	}
	if (t2.compatible(*this)) {
		return t2;
	}
	if (compatible(t2)) {
		return *this;
	}
	if (is_array() and t2.is_array()) {
		if (element().is_polymorphic() and t2.element().is_polymorphic()) {
			return array(any());
		}
	}
	return Type::any();
}
Пример #10
0
Cell eval(Cell exp, Cell env) {

    if (is_self_evaluating(exp)) {
        return exp;
    } else if (is_atom(exp)) {
        return lookup(exp, env);
    } else if (is_tagged(exp, atom("define"))) {
        return define(car(cdr(exp)), eval(car(cdr(cdr(exp))), env), env);
    } else if (is_tagged(exp, atom("set!"))) {
        return set(car(cdr(exp)), eval(car(cdr(cdr(exp))), env), env);
    } else if (is_tagged(exp, atom("if"))) {
        Cell cond = eval(car(cdr(exp)), env);
        if (is_atom(cond) && is_eq(cond, atom("#f"))) {
           exp = car(cdr(cdr(cdr(exp))));
        } else {
           exp = car(cdr(cdr(exp)));
        }
        return eval(exp, env);
    } else if (is_tagged(exp, atom("vau"))) {
        return procedure(exp, env);
    } else if (is_pair(exp)) {
        Cell proc = eval(car(exp), env);
        if (is_primitive(proc)) {
            return (proc->primitive)(eval_operands(cdr(exp), env));
        } else if (is_procedure(proc)) {
            Cell src = car(proc);
            Cell e = car(cdr(cdr(src)));
            Cell para = cons(e, cons(car(cdr(src)), null));
            Cell args = cons(env, cons(cdr(exp), null));
            Cell body = car(cdr(cdr(cdr(src))));
            return eval(body, extend_env(para, args, cdr(proc)));
        }
    }
    fprintf(stderr, "eval illegal state\n");
    return atom("#<void>");
}
Пример #11
0
/**************************************************************************
 *
 *N  select_feature_class_relate
 *
 *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *    Set up the relationships between features and primitives or between
 *    primitives and features (one way only) for a specified feature class.
 *E
 *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Barry Michaels  DOS Turbo C
 *E
 *************************************************************************/
fcrel_type select_feature_class_relate( int fcnum,
					library_type *library,
					char *start_table,
					char *end_table )
{
   int storage, cov;
   vpf_table_type fcs;
   long int i;
   char path[255], covpath[255];
   position_type p;
   vpf_relate_struct rcell;
   fcrel_type fcrel;

   fcrel.nchain = 0;
   fcrel.table = NULL;
   fcrel.relate_list = NULL;

   cov = library->fc[fcnum].coverage;
   strcpy(covpath,library->cover[cov].path);
   rightjust(covpath);
   sprintf( path, "%sfcs", covpath );

   /* Feature Class Schema table */
   fcs = vpf_open_table( path, disk, "rb", NULL );

   fcrel.relate_list = fcs_relate_list( library->fc[fcnum].name,
					start_table,end_table,
					fcs );

   if (ll_empty(fcrel.relate_list)) {
      ll_reset(fcrel.relate_list);
      displaymessage("ERROR in feature class relationship!",
		     start_table,end_table,NULL);
      return fcrel;
   }

   /* Find the number of tables in the relate chain */
   p = ll_first(fcrel.relate_list);
   fcrel.nchain = 0;
   while (!ll_end(p)) {
      fcrel.nchain++;
      p = ll_next(p);
   }
   /* Allow for last table2 */
   fcrel.nchain++;

   fcrel.table = (vpf_table_type *)
		  vpfmalloc((fcrel.nchain+1)*
			     sizeof(vpf_table_type));

   for (i=0;i<fcrel.nchain+1;i++)
      vpf_nullify_table( &(fcrel.table[i]) );


   p = ll_first(fcrel.relate_list);
   for (i=0;i<fcrel.nchain-1;i++) {

      ll_element(p,&rcell);

      /** Can't open primitive table - may be several under tile **/
      /** directories.  Open all others **/
      if (!is_primitive(rcell.table1)) {

	 sprintf(path,"%s%s",covpath,rcell.table1);
	 if (is_join(rcell.table1))
	    storage = ram;
	 else
	    storage = disk;

	 fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL);

      }

      if (!ll_end(p)) p = ll_next(p);
   }

   /* End of relate chain */
   i = fcrel.nchain-1;
   if (!is_primitive(rcell.table2)) {

      sprintf(path,"%s%s",covpath,rcell.table2);
      storage = disk;

      fcrel.table[i] = vpf_open_table(path,(storage_type)storage,"rb",NULL);

   }


   vpf_close_table( &fcs );

   return fcrel;
}
Пример #12
0
bool Type::is_boolifiable() const {
    return is_top() || is_primitive() || is_ref();
}
Пример #13
0
bool Type::is_compound() const {
    return is_value() && !is_primitive();
}
Пример #14
0
bool Type::is_value() const {
    Class* cls = clazz();
    return is_primitive() || is_value_proto() 
        || (cls && cls->proto()->is_value_proto()); 
}
Пример #15
0
int is_eval(lisp_object_t proc) {
  return is_primitive(proc) && eval_proc == primitive_C_proc(proc);
}