Esempio n. 1
0
LONG cop_request(LONG cob_id, SHORT *length, BYTE *data)
{
	WORD timeout[9] = {2,2,2,2,2,2,5,10,20};
	BYTE dlc = (BYTE)*length;

	// 1. Configure receive message object with remote request
	if((cop_error = can_config(CANBUF_RX, cob_id, (WORD)CAN_REQUEST(dlc))) != CANERR_NOERROR) {
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 2. Start timer (increased time-out for RTR-frames)
	can_start_timer((WORD)(timeout[cop_baudrate] * CANRTR_FACTOR));

	// 3. Wait until message is received
	do {
		// Return if a message is received, or an error occurred
		if((cop_error = can_receive(CANBUF_RX, length, data)) != COPERR_RX_EMPTY) {
			can_delete(CANBUF_RX);
			return cop_error;
		}
	} while(!can_is_timeout());
	// 4. A time-out occurred!
	can_delete(CANBUF_RX);
	return cop_error = COPERR_TIMEOUT;
}
Esempio n. 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);
      }
    }
  }
}
Esempio n. 3
0
void reportReachableClasses(const Scope& scope, std::string reportFileName) {
  TRACE(PGR, 4, "Total numner of classes: %d\n", scope.size());
  // Report classes that the reflection filter says can't be deleted.
  std::ofstream reportFileCanDelete(reportFileName + ".cant_delete");
  for (auto const& cls : scope) {
    if (!can_delete(cls)) {
      reportFileCanDelete << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileCanDelete.close();
  // Report classes that the reflection filter says can't be renamed.
  std::ofstream reportFileCanRename(reportFileName + ".cant_rename");
  for (auto const& cls : scope) {
    if (!can_rename(cls)) {
      reportFileCanRename << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileCanRename.close();
  // Report classes marked for keep from ProGuard flat file list.
  std::ofstream reportFileKeep(reportFileName + ".must_keep");
  for (auto const& cls : scope) {
    if (is_seed(cls)) {
      reportFileKeep << cls->get_name()->c_str() << "\n";
    }
  }
  reportFileKeep.close();
}
Esempio n. 4
0
/* unlink can delete the (disk or memory)inode directly. */
int minix_inode_unlink(struct inode *dir, char *base, int len,
			int (*can_delete)(struct inode *))
{
	struct block *block;		/* dir entry block */
	struct minix_dentry *de;
	struct inode *inode;
	int r = -1;

	de = minix_lookup_dentry(dir, base, len, &block);
	if (!de)
		return -1;
	inode = minix_get_inode(dir->i_sb, de->d_ino);
	if (!inode)
		goto out_put_block;
	/* permission check */
	if (inode->i_refcnt > 1)
		goto out_put_inode;
	if (can_delete && !can_delete(inode))
		goto out_put_inode;

	/* delete it from the data block of dir */
	memset(de, 0x0, MINIX_DENTRY_SIZE);
	minix_inode_dirty_block(dir, block);
	/* delete inode */
	minix_dec_link(inode);
	minix_put_inode(inode);
	r = 0;
out_put_inode:
	put_inode(inode);
out_put_block:
	put_block(block);
	return r;
}
Esempio n. 5
0
LONG cop_transmit(LONG cob_id, SHORT length, BYTE *data)
{
	// 1. Configure transmit message object
	if((cop_error = can_config(CANBUF_TX, cob_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		return cop_error;
	}
	// 2. Transmit the message
	if((cop_error = can_transmit(CANBUF_TX, length, data)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		return cop_error;
	}
	// Return if the message is transmitted
	can_delete(CANBUF_TX);
	return cop_error;
}
Esempio n. 6
0
bool should_rename(DexClass *clazz,
    std::vector<std::string>& pre_patterns,
    std::vector<std::string>& post_patterns,
    std::unordered_set<const DexType*>& untouchables,
    bool rename_annotations,
    PassManager& mgr) {
  if (!rename_annotations && is_annotation(clazz)) {
    mgr.incr_metric(METRIC_CANT_RENAME_ANNOTATION, 1);
    return false;
  }
  if (untouchables.count(clazz->get_type())) {
    mgr.incr_metric(METRIC_CANT_RENAME_UNTOUCHABLE, 1);
    return false;
  }
  auto chstring = clazz->get_type()->get_name()->c_str();
  /* We're assuming anonymous classes are safe always safe to rename. */
  auto last_cash = strrchr(chstring, '$');
  if (last_cash != nullptr) {
    auto val = *++last_cash;
    if (val >= '0' && val <= '9') {
      match_inner++;
      return true;
    }
  }
  /* Check for more aggressive, but finer grained filters first */
  for (auto p : pre_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  if (!can_rename(clazz) && !can_delete(clazz)) {
    mgr.incr_metric(METRIC_CANT_RENAME_AND_CANT_DELETE, 1);
    return false;
  }
  /* Check for wider, less precise filters */
  for (auto p : post_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  mgr.incr_metric(METRIC_NOT_WHITELISTED, 1);
  return false;
}
Esempio n. 7
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);
      }
    }
  }
}
Esempio n. 8
0
bool should_rename(DexClass *clazz,
    std::vector<std::string>& pre_patterns,
    std::vector<std::string>& post_patterns,
    std::unordered_set<const DexType*>& untouchables,
    bool rename_annotations) {
  if (!rename_annotations && is_annotation(clazz)) return false;
  if (untouchables.count(clazz->get_type())) return false;
  auto chstring = clazz->get_type()->get_name()->c_str();
  /* We're assuming anonymous classes are safe always safe to rename. */
  auto substr = strrchr(chstring, '$');
  if (substr != nullptr) {
    auto val = *++substr;
    if (val >= '0' && val <= '9') {
      match_inner++;
      return true;
    }
  }
  /* Check for more aggressive, but finer grained filters first */
  for (auto p : pre_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  if (!can_rename(clazz) && !can_delete(clazz)) {
    return false;
  }
  /* Check for wider, less precise filters */
  for (auto p : post_patterns) {
    auto substr = strstr(chstring, p.c_str());
    if (substr != nullptr) {
      if (p.length() > 1) {
        match_long++;
      } else {
        match_short++;
      }
      return true;
    }
  }
  return false;
}
HRESULT STDMETHODCALLTYPE CProjectItemInfo::get_InfoProperty(TC_PROJECT_NODE_INFO_PROP PropID, VARIANT * Value)
{
	_ASSERT( Value != NULL );

	CComVariant default_node_name     (cDefaultName);
	CComVariant bitmap                ((LONG)m_bitmap);
	CComVariant name                  (cProjectItemName);
	CComVariant description           (cProjectItemDescription);
	CComVariant description_ex        (cProjectItemDescription_ex);
	CComVariant help_context          (0);
	CComVariant help_context_file_name(_T(""));
	CComVariant help_topic            (_T(""));
	CComVariant help_topic_file_name  (_T(""));
	CComVariant is_alone              (true);
	CComVariant is_required           (false);
	CComVariant can_edit_name         (false);
	CComVariant can_delete            (true);
	CComVariant recorder_create_only  (false);

	switch (PropID)
	{
		case pniDefaultNodeName:     return VariantCopy(Value, &default_node_name);
		case pniBitmapReference:     return VariantCopy(Value, &bitmap);
		case pniName:                return VariantCopy(Value, &name);
		case pniDescription:         return VariantCopy(Value, &description);
		case pniDescriptionEx:       return VariantCopy(Value, &description_ex);
		case pniHelpContext:         return VariantCopy(Value, &help_context);
		case pniHelpContextFileName: return VariantCopy(Value, &help_context_file_name);
		case pniHelpTopic:           return VariantCopy(Value, &help_topic);
		case pniHelpTopicFileName:   return VariantCopy(Value, &help_topic_file_name);
		case pniIsAlone:             return VariantCopy(Value, &is_alone);
		case pniIsRequired:          return VariantCopy(Value, &is_required);
		case pniCanEditName:         return VariantCopy(Value, &can_edit_name);
		case pniCanDelete:           return VariantCopy(Value, &can_delete);
		case pniRecorderCreateOnly:  return VariantCopy(Value, &recorder_create_only);
		default:
			_ASSERT( false );
			return ERROR_BAD_ARGUMENTS;
	}
}
Esempio n. 10
0
static LONG sdo_receive(BYTE node_id, WORD index, BYTE subindex, SHORT *length, BYTE *data, SHORT max)
{
	short n;							// data length code
	short rc;							// return value
	short t = 0;						// toggle bit
	
	// ---  Initiate SDO Upload  ---
	cop_buffer[0] = 0x40;				// client command specifier
	cop_buffer[1] = LOBYTE(index);		// multiplexor: index (LSB)
	cop_buffer[2] = HIBYTE(index);		//              index (MSB)
	cop_buffer[3] = (BYTE)(subindex);	//              subindex
	cop_buffer[4] = 0x00;				// reserved: set to 00h
	cop_buffer[5] = 0x00;				//   -"-
	cop_buffer[6] = 0x00;				//   -"-
	cop_buffer[7] = 0x00;				//   -"-
	n = 8;								// 8 bytes to transmit!

	// 1. Configure transmit message object for client SDO
	if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		return cop_error;
	}
	// 2. Configure receive message object for server SDO 
	if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 2. Transmit the client SDO message
	if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 3. Start timer for SDO time-out
	can_start_timer(cop_timeout);

	// 4. Wait until server message is received
	do	{
		switch((rc = can_receive(CANBUF_RX, &n, cop_buffer)))
		{
		case CANERR_NOERROR:			// confirmation:
			if(n != 8) {								// 8 bytes received?
				cop_error = SDOERR_GENERAL_ERROR;		//   abort: general error
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
			   *length = 0;								//   no data received!
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_LENGTH;
			}
			if((cop_buffer[1] != LOBYTE(index)) ||		// multiplexor? index (LSB)
			   (cop_buffer[2] != HIBYTE(index)) ||		//              index (MSB)
			   (cop_buffer[3] != (BYTE)(subindex))) {	//              subindex
				rc = COPERR_FORMAT;
				break;
			}
			if((cop_buffer[0] & 0xE0) == 0x80) {// SDO abort received?
				LOLOBYTE(cop_error) = cop_buffer[4];	//   abort code (LSB)
				LOHIBYTE(cop_error) = cop_buffer[5];	//    -"-
				HILOBYTE(cop_error) = cop_buffer[6];	//    -"-
				HIHIBYTE(cop_error) = cop_buffer[7];	//   abort code (MSB)
			   *length = 0;								//   no data received!
				// Return value is abort code!
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error;
			}
			if((cop_buffer[0] & 0xE0) != 0x40) {		// unknown command specifier?
				cop_error = SDOERR_UNKNOWN_SPECIFIER;	//   abort: unknown command specifier
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
			   *length = 0;								//   no data received!
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_FORMAT;
			}
			if((cop_buffer[0] & 0x02) == 0x02) {		// expedited transfer?
				if((cop_buffer[0] & 0x01) == 0x01)
					n = 4 - (short)((cop_buffer[0] & 0x0C) >> 2);
				else
					n = 4;
				memcpy(data, &cop_buffer[4], n < max? n : max);
			   *length = n < max? n : max;				//   data received!!!
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_NOERROR;
			}
			break;
		case CANERR_RX_EMPTY:				// receiver empty:
			if(can_is_timeout()) {						//   time-out occurred?
				cop_error = SDOERR_PROTOCOL_TIMEOUT;	//   abort: time-out
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
			   *length = 0;								//   no data received!
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_TIMEOUT;
			}
			break;
		default:							// other errors:
			cop_error = SDOERR_GENERAL_ERROR;			//   abort: general error
			cop_buffer[0] = 0x80;						//   command specifier
			cop_buffer[1] = LOBYTE(index);				//   multiplexor: index (LSB)
			cop_buffer[2] = HIBYTE(index);				//                index (MSB)
			cop_buffer[3] = (BYTE)(subindex);			//            subindex
			cop_buffer[4] = LOLOBYTE(cop_error);		// abort code (LSB)
			cop_buffer[5] = LOHIBYTE(cop_error);		//  -"-
			cop_buffer[6] = HILOBYTE(cop_error);		//  -"-
			cop_buffer[7] = HIHIBYTE(cop_error);		// abort code (MSB)
		   *length = 0;									//   no data received!
			// Transmit SDO abort and return
			can_transmit(CANBUF_TX, 8, cop_buffer);
			can_delete(CANBUF_TX);
			can_delete(CANBUF_RX);
			return cop_error = rc;
		}
	}	while(rc != CANERR_NOERROR);		// segmented transfer:

	// ---  Upload SDO Segment  ---
	for(*length = 0;;)
	{
		cop_buffer[0] = 0x60 | t;		// client command specifier
		cop_buffer[1] = 0x00;			// reserved: set to 00h
		cop_buffer[2] = 0x00;			//   -"-
		cop_buffer[3] = 0x00;			//   -"-
		cop_buffer[4] = 0x00;			//   -"-
		cop_buffer[5] = 0x00;			//   -"-
		cop_buffer[6] = 0x00;			//   -"-
		cop_buffer[7] = 0x00;			//   -"-
		n = 8;							// 8 bytes to transmit!

		// 5. Transmit the client SDO message
		if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) {
			can_delete(CANBUF_TX);
			can_delete(CANBUF_RX);
			return cop_error;
		}
		// 6. Start timer for SDO time-out
		can_start_timer(cop_timeout);

		// 7. Wait until server message is received
		do	{
			switch((rc = can_receive(CANBUF_RX, &n, cop_buffer)))
			{
			case CANERR_NOERROR:			// confirmation:
				if(n != 8) {								// 8 bytes received?
					cop_error = SDOERR_GENERAL_ERROR;		//   abort: general error
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				   *length = 0;								//   no data received!
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_LENGTH;
				}
				if((cop_buffer[0] & 0xE0) == 0x80) {// SDO abort received?
					LOLOBYTE(cop_error) = cop_buffer[4];	//   abort code (LSB)
					LOHIBYTE(cop_error) = cop_buffer[5];	//    -"-
					HILOBYTE(cop_error) = cop_buffer[6];	//    -"-
					HIHIBYTE(cop_error) = cop_buffer[7];	//   abort code (MSB)
				   *length = 0;								//   no data received!
					// Return value is abort code!
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error;
				}
				if((cop_buffer[0] & 0xE0) != 0x00) {		// unknown command specifier?
					cop_error = SDOERR_UNKNOWN_SPECIFIER;	//   abort: unknown command specifier
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				   *length = 0;								//   no data received!
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_FORMAT;
				}
				if((cop_buffer[0] & 0x10) != t) {			// toggle bit not altered?
					cop_error = SDOERR_WRONG_TOGGLEBIT;		//   abort: toggle bit not altered
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//  abort code (MSB)
				   *length = 0;								//   no data received!
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_FORMAT;
				}
				if((cop_buffer[0] & 0x0E) != 0x00)			// number of segment data bytes
					n = 7 - (int)((cop_buffer[0] & 0x0E) >> 1);
				else
					n = 7;
				if(max - *length > 0)						// copy segment data if space
					memcpy(&data[*length], &cop_buffer[1], *length + n < max? n : max - *length);
			   *length += n;
				if((cop_buffer[0] & 0x01) == 0x01) {		// no more segments?
					if(*length > max)
					   *length = max;						//   truncate to buffer size!
					if(*length < max)
						data[*length] = '\0';				//   for zero-closed strings!
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_NOERROR;
				}
				break;
			case CANERR_RX_EMPTY:				// receiver empty:
				if(can_is_timeout()) {						//   time-out occurred?
					cop_error = SDOERR_PROTOCOL_TIMEOUT;	//   abort: time-out
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				   *length = 0;								//   no data received!
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_TIMEOUT;
				}
				break;
			default:							// other errors:
				cop_error = SDOERR_GENERAL_ERROR;			//   abort: general error
				cop_buffer[0] = 0x80;						//   command specifier
				cop_buffer[1] = LOBYTE(index);				//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);				//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);			//            subindex
				cop_buffer[4] = LOLOBYTE(cop_error);		// abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);		//  -"-
				cop_buffer[6] = HILOBYTE(cop_error);		//  -"-
				cop_buffer[7] = HIHIBYTE(cop_error);		// abort code (MSB)
			   *length = 0;									//   no data received!
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = rc;
			}
		}	while(rc != CANERR_NOERROR);

		t = t? 0x00 : 0x10;				// alternate toggle bit!
	}	
}
Esempio n. 11
0
static LONG sdo_segmented(BYTE node_id, WORD index, BYTE subindex, SHORT length, BYTE *data)
{
	short n, i;							// data length code
	short rc;							// return value
	short t = 0;						// toggle bit
	
	// ---  Initiate SDO Download  ---
	cop_buffer[0] = (BYTE)0x21;			// client command specifier
	cop_buffer[1] = LOBYTE(index);		// multiplexor: index (LSB)
	cop_buffer[2] = HIBYTE(index);		//              index (MSB)
	cop_buffer[3] = (BYTE)(subindex);	//              subindex
	cop_buffer[4] = LOBYTE(length);		// number of data bytes (LSB)
	cop_buffer[5] = HIBYTE(length);		//  -"-
	cop_buffer[6] = (BYTE)0x00;			//  -"-
	cop_buffer[7] = (BYTE)0x00;			// number of data bytes (MSB)
	n = 8;								// 8 bytes to transmit!

	// 1. Configure transmit message object for client SDO
	if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		return cop_error;
	}
	// 2. Configure receive message object for server SDO 
	if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 2. Transmit the client SDO message
	if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 3. Start timer for SDO time-out
	can_start_timer(cop_timeout);

	// 4. Wait until server message is received
	do	{
		switch((rc = can_receive(CANBUF_RX, &n, cop_buffer)))
		{
		case CANERR_NOERROR:			// confirmation:
			if(n != 8) {								// 8 bytes received?
				cop_error = SDOERR_GENERAL_ERROR;		//   abort: general error
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_LENGTH;
			}
			if((cop_buffer[1] != LOBYTE(index)) ||		// multiplexor? index (LSB)
			   (cop_buffer[2] != HIBYTE(index)) ||		//              index (MSB)
			   (cop_buffer[3] != (BYTE)(subindex))) {	//              subindex
				rc = COPERR_FORMAT;
				break;
			}
			if((cop_buffer[0] & 0xFF) == 0x80) {		// SDO abort received?
				LOLOBYTE(cop_error) = cop_buffer[4];	//   abort code (LSB)
				LOHIBYTE(cop_error) = cop_buffer[5];	//    -"-
				HILOBYTE(cop_error) = cop_buffer[6];	//    -"-
				HIHIBYTE(cop_error) = cop_buffer[7];	//   abort code (MSB)
				// Return value is abort code!
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error;
			}
			if((cop_buffer[0] & 0xFF) != 0x60) {		// unknown command specifier?
				cop_error = SDOERR_UNKNOWN_SPECIFIER;	//   abort: unknown command specifier
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_FORMAT;
			}
		case CANERR_RX_EMPTY:			// receiver empty:
			if(can_is_timeout()) {						//   time-out occurred?
				cop_error = SDOERR_PROTOCOL_TIMEOUT;	//   abort: time-out
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_TIMEOUT;
			}
			break;
		default:						// other errors:
			cop_error = SDOERR_GENERAL_ERROR;			//   abort: general error
			cop_buffer[0] = 0x80;						//   command specifier
			cop_buffer[1] = LOBYTE(index);				//   multiplexor: index (LSB)
			cop_buffer[2] = HIBYTE(index);				//                index (MSB)
			cop_buffer[3] = (BYTE)(subindex);			//            subindex
			cop_buffer[4] = LOLOBYTE(cop_error);		// abort code (LSB)
			cop_buffer[5] = LOHIBYTE(cop_error);		//  -"-
			cop_buffer[6] = HILOBYTE(cop_error);		//  -"-
			cop_buffer[7] = HIHIBYTE(cop_error);		// abort code (MSB)
			// Transmit SDO abort and return
			can_transmit(CANBUF_TX, 8, cop_buffer);
			can_delete(CANBUF_TX);
			can_delete(CANBUF_RX);
			return cop_error = rc;
		}
	}	while(rc != CANERR_NOERROR);

	// ---  Download SDO Segment  ---
	for(i = 0;;)
	{
		if(length <= 7)					// bytes that does not contain data
			n = 7 - length;
		else							// no segment size indicated
			n = 0;
		cop_buffer[0] = (BYTE)(n << 1);	// client command specifier
		memset(&cop_buffer[1], 0x00, 7);// clear data buffer
		memcpy(&cop_buffer[1], &data[i], 7 - n);// copy segment data
		length -= 7 - n;				// remaining number of bytes
		i	   += 7 - n;				// index to remainung bytes
		cop_buffer[0]|= length? 0x00 : 0x01;// last segment to transmit
		cop_buffer[0]|= t;				// toggle bit
		n = 8;							// 8 bytes to transmit!

		// 5. Transmit the client SDO message
		if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) {
			can_delete(CANBUF_TX);
			can_delete(CANBUF_RX);
			return cop_error;
		}
		// 6. Start timer for SDO time-out
		can_start_timer(cop_timeout);

		// 7. Wait until server message is received
		do	{
			switch((rc = can_receive(CANBUF_RX, &n, cop_buffer)))
			{
			case CANERR_NOERROR:			// confirmation:
				if(n != 8) {								// 8 bytes received?
					cop_error = SDOERR_GENERAL_ERROR;		//   abort: general error
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_LENGTH;
				}
				if((cop_buffer[0] & 0xE0) == 0x80) {		// SDO abort received?
					LOLOBYTE(cop_error) = cop_buffer[4];	//   abort code (LSB)
					LOHIBYTE(cop_error) = cop_buffer[5];	//    -"-
					HILOBYTE(cop_error) = cop_buffer[6];	//    -"-
					HIHIBYTE(cop_error) = cop_buffer[7];	//   abort code (MSB)
					// Return value is abort code!
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error;
				}
				if((cop_buffer[0] & 0xE0) != 0x20) {		// unknown command specifier?
					cop_error = SDOERR_UNKNOWN_SPECIFIER;	//   abort: unknown command specifier
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_FORMAT;
				}
				if((cop_buffer[0] & 0x10) != t) {			// toggle bit not altered?
					cop_error = SDOERR_WRONG_TOGGLEBIT;		//   abort: toggle bit not altered
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_FORMAT;
				}
				if(length == 0)	{							// all data tranmitted?
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_NOERROR;
				}
			case CANERR_RX_EMPTY:			// receiver empty:
				if(can_is_timeout()) {						//   time-out occurred?
					cop_error = SDOERR_PROTOCOL_TIMEOUT;	//   abort: time-out
					cop_buffer[0] = 0x80;					//   command specifier
					cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
					cop_buffer[2] = HIBYTE(index);			//                index (MSB)
					cop_buffer[3] = (BYTE)(subindex);		//                subindex
					cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
					cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
					cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
					cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
					// Transmit SDO abort and return
					can_transmit(CANBUF_TX, 8, cop_buffer);
					can_delete(CANBUF_TX);
					can_delete(CANBUF_RX);
					return cop_error = COPERR_TIMEOUT;
				}
				break;
			default:						// other errors:
				cop_error = SDOERR_GENERAL_ERROR;			//   abort: general error
				cop_buffer[0] = 0x80;						//   command specifier
				cop_buffer[1] = LOBYTE(index);				//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);				//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);			//            subindex
				cop_buffer[4] = LOLOBYTE(cop_error);		// abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);		//  -"-
				cop_buffer[6] = HILOBYTE(cop_error);		//  -"-
				cop_buffer[7] = HIHIBYTE(cop_error);		// abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = rc;
			}
		}	while(rc != CANERR_NOERROR);

		t = t? 0x00 : 0x10;				// alternate toggle bit!
	}
}
Esempio n. 12
0
static LONG sdo_expedited(BYTE node_id, WORD index, BYTE subindex, SHORT length, BYTE *data)
{
	short n;							// data length code
	short rc;							// return value
	
	// ---  Expedited SDO Download  ---
	cop_buffer[0]  = (BYTE)0x23;		// client command specifier
	cop_buffer[0] |= (BYTE)((4 - length) << 2);
	cop_buffer[1]  = LOBYTE(index);		// multiplexor: index (LSB)
	cop_buffer[2]  = HIBYTE(index);		//              index (MSB)
	cop_buffer[3]  = (BYTE)(subindex);	//              subindex
	memset(&cop_buffer[4],0x00,4);		// clear data buffer
	memcpy(&cop_buffer[4],data,length);	// copy data bytes
	n = 8;								// 8 bytes to transmit!

	// 1. Configure transmit message object for client SDO
	if((cop_error = can_config(CANBUF_TX, SDO_CLIENT + node_id, CANMSG_TRANSMIT)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		return cop_error;
	}
	// 2. Configure receive message object for server SDO 
	if((cop_error = can_config(CANBUF_RX, SDO_SERVER + node_id, CANMSG_RECEIVE)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 2. Transmit the client SDO message
	if((cop_error = can_transmit(CANBUF_TX, n, cop_buffer)) != CANERR_NOERROR) {
		can_delete(CANBUF_TX);
		can_delete(CANBUF_RX);
		return cop_error;
	}
	// 3. Start timer for SDO time-out
	can_start_timer(cop_timeout);

	// 4. Wait until server message is received
	do	{
		switch((rc = can_receive(CANBUF_RX, &n, cop_buffer)))
		{
		case CANERR_NOERROR:			// confirmation:
			if(n != 8) {								// 8 bytes received?
				cop_error = SDOERR_GENERAL_ERROR;		//   abort: general error
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_LENGTH;
			}
			if((cop_buffer[1] != LOBYTE(index)) ||		// multiplexor? index (LSB)
			   (cop_buffer[2] != HIBYTE(index)) ||		//              index (MSB)
			   (cop_buffer[3] != (BYTE)(subindex))) {	//              subindex
				rc = COPERR_FORMAT;
				break;
			}
			if((cop_buffer[0] & 0xFF) == 0x80) {		// SDO abort received?
				LOLOBYTE(cop_error) = cop_buffer[4];	//   abort code (LSB)
				LOHIBYTE(cop_error) = cop_buffer[5];	//    -"-
				HILOBYTE(cop_error) = cop_buffer[6];	//    -"-
				HIHIBYTE(cop_error) = cop_buffer[7];	//   abort code (MSB)
				// Return value is abort code!
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error;
			}
			if((cop_buffer[0] & 0xFF) != 0x60) {		// unknown command specifier?
				cop_error = SDOERR_UNKNOWN_SPECIFIER;	//   abort: unknown command specifier
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_FORMAT;
			}
			else {										// success: data written!
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_NOERROR;
			}
		case CANERR_RX_EMPTY:			// receiver empty:
			if(can_is_timeout()) {						//   time-out occurred?
				cop_error = SDOERR_PROTOCOL_TIMEOUT;	//   abort: time-out
				cop_buffer[0] = 0x80;					//   command specifier
				cop_buffer[1] = LOBYTE(index);			//   multiplexor: index (LSB)
				cop_buffer[2] = HIBYTE(index);			//                index (MSB)
				cop_buffer[3] = (BYTE)(subindex);		//                subindex
				cop_buffer[4] = LOLOBYTE(cop_error);	//   abort code (LSB)
				cop_buffer[5] = LOHIBYTE(cop_error);	//    -"-
				cop_buffer[6] = HILOBYTE(cop_error);	//    -"-
				cop_buffer[7] = HIHIBYTE(cop_error);	//   abort code (MSB)
				// Transmit SDO abort and return
				can_transmit(CANBUF_TX, 8, cop_buffer);
				can_delete(CANBUF_TX);
				can_delete(CANBUF_RX);
				return cop_error = COPERR_TIMEOUT;
			}
			break;
		default:						// other errors:
			cop_error = SDOERR_GENERAL_ERROR;			//   abort: general error
			cop_buffer[0] = 0x80;						//   command specifier
			cop_buffer[1] = LOBYTE(index);				//   multiplexor: index (LSB)
			cop_buffer[2] = HIBYTE(index);				//                index (MSB)
			cop_buffer[3] = (BYTE)(subindex);			//            subindex
			cop_buffer[4] = LOLOBYTE(cop_error);		// abort code (LSB)
			cop_buffer[5] = LOHIBYTE(cop_error);		//  -"-
			cop_buffer[6] = HILOBYTE(cop_error);		//  -"-
			cop_buffer[7] = HIHIBYTE(cop_error);		// abort code (MSB)
			// Transmit SDO abort and return
			can_transmit(CANBUF_TX, 8, cop_buffer);
			can_delete(CANBUF_TX);
			can_delete(CANBUF_RX);
			return cop_error = rc;
		}
	}	while(1);						// "the torture never stops!"
}
Esempio n. 13
0
/**
 * Collect all non virtual methods and make all small methods candidates
 * for inlining.
 */
std::unordered_set<DexMethod*> SimpleInlinePass::gather_non_virtual_methods(
    Scope& scope, const std::unordered_set<DexType*>& no_inline) {
  // trace counter
  size_t all_methods = 0;
  size_t direct_methods = 0;
  size_t direct_no_code = 0;
  size_t non_virtual_no_code = 0;
  size_t clinit = 0;
  size_t init = 0;
  size_t static_methods = 0;
  size_t private_methods = 0;
  size_t dont_strip = 0;
  size_t no_inline_anno_count = 0;
  size_t non_virt_dont_strip = 0;
  size_t non_virt_methods = 0;

  // collect all non virtual methods (dmethods and vmethods)
  std::unordered_set<DexMethod*> methods;

  const auto can_inline_method = [&](DexMethod* meth, DexCode* code) {
    if (has_anno(type_class(meth->get_class()), no_inline) ||
        has_anno(meth, no_inline)) {
      no_inline_anno_count++;
      return;
    }
    if (code->get_instructions().size() < SMALL_CODE_SIZE) {
      // always inline small methods even if they are not deletable
      inlinable.insert(meth);
    } else {
      if (!can_delete(meth)) {
        // never inline methods that cannot be deleted
        TRACE(SINL, 4, "cannot_delete: %s\n", SHOW(meth));
        dont_strip++;
      } else {
        methods.insert(meth);
      }
    }
  };

  walk_methods(scope,
      [&](DexMethod* method) {
        all_methods++;
        if (method->is_virtual()) return;

        auto code = method->get_code();
        bool dont_inline = code == nullptr;

        direct_methods++;
        if (code == nullptr) direct_no_code++;
        if (is_constructor(method)) {
          (is_static(method)) ? clinit++ : init++;
          dont_inline = true;
        } else {
          (is_static(method)) ? static_methods++ : private_methods++;
        }

        if (dont_inline) return;

        can_inline_method(method, code);
      });
  if (m_virtual_inline) {
    auto non_virtual = devirtualize(scope);
    non_virt_methods = non_virtual.size();
    for (const auto& vmeth : non_virtual) {
      auto code = vmeth->get_code();
      if (code == nullptr) {
        non_virtual_no_code++;
        continue;
      }
      can_inline_method(vmeth, code);
    }
  }

  TRACE(SINL, 2, "All methods count: %ld\n", all_methods);
  TRACE(SINL, 2, "Direct methods count: %ld\n", direct_methods);
  TRACE(SINL, 2, "Virtual methods count: %ld\n", all_methods - direct_methods);
  TRACE(SINL, 2, "Direct methods no code: %ld\n", direct_no_code);
  TRACE(SINL, 2, "Direct methods with code: %ld\n",
      direct_methods - direct_no_code);
  TRACE(SINL, 2, "Constructors with or without code: %ld\n", init);
  TRACE(SINL, 2, "Static constructors: %ld\n", clinit);
  TRACE(SINL, 2, "Static methods: %ld\n", static_methods);
  TRACE(SINL, 2, "Private methods: %ld\n", private_methods);
  TRACE(SINL, 2, "Virtual methods non virtual count: %ld\n", non_virt_methods);
  TRACE(SINL, 2, "Non virtual no code count: %ld\n", non_virtual_no_code);
  TRACE(SINL, 2, "Non virtual no strip count: %ld\n", non_virt_dont_strip);
  TRACE(SINL, 2, "Small methods: %ld\n", inlinable.size());
  TRACE(SINL, 2, "Don't strip inlinable methods count: %ld\n", dont_strip);
  TRACE(SINL, 2, "Don't inline annotation count: %ld\n", no_inline_anno_count);
  return methods;
}