Exemple #1
0
boolean dispatch_static_initializer (ClassRecord *aRec, byte *retAddr)
{
  if (is_initialized (aRec))
    return false;
  set_initialized (aRec);
  if (!has_clinit (aRec))
    return false;
  #if DEBUG_METHODS
  printf ("dispatch_static_initializer: has clinit: %d, %d\n",
          (int) aRec, (int) retAddr);
  #endif
  dispatch_special (find_method (aRec, _6clinit_7_4_5V), retAddr);
  return true;
}
Exemple #2
0
/**
 * Calls static initializer if necessary before
 * dispatching with dispatch_special().
 * @param retAddr Return bytecode address.
 * @param btAddr Backtrack bytecode address (in case
 *               static initializer is executed).
 */
void dispatch_special_checked (byte classIndex, byte methodIndex,
                               byte *retAddr, byte *btAddr)
{
  ClassRecord *classRecord;

  #if DEBUG_METHODS
  printf ("dispatch_special_checked: %d, %d, %d, %d\n",
          classIndex, methodIndex, (int) retAddr, (int) btAddr);
  #endif

  classRecord = get_class_record (classIndex);
  if (dispatch_static_initializer (classRecord, btAddr))
    return;
  dispatch_special (get_method_record (classRecord, methodIndex), retAddr);
}
Exemple #3
0
void dispatch_virtual (Object *ref, int signature, byte *retAddr)
{
  ClassRecord *classRecord;
  MethodRecord *methodRecord;
  int classIndex;

#if DEBUG_METHODS
  printf("dispatch_virtual %d\n", signature);
#endif
  if (ref == JNULL)
  {
    throw_new_exception (JAVA_LANG_NULLPOINTEREXCEPTION);
    return;
  }
  // When calling methods on arrays, we use the methods for the Object class...
  classIndex = get_class_index(ref);
 LABEL_METHODLOOKUP:
  classRecord = get_class_record (classIndex);
  methodRecord = find_method (classRecord, signature);
  if (methodRecord == null)
  {
    #if SAFE
    if (classIndex == JAVA_LANG_OBJECT)
    {
      throw_new_exception (JAVA_LANG_NOSUCHMETHODERROR);
      return;
    }
    #endif
    classIndex = classRecord->parentClass;
    goto LABEL_METHODLOOKUP;
  }

  if (dispatch_special (methodRecord, retAddr))
  {
    if (is_synchronized(methodRecord))
    {
      current_stackframe()->monitor = ref;
      enter_monitor (currentThread, ref);
    }
  }
}
Exemple #4
0
void dispatch_virtual (Object *ref, TWOBYTES signature, byte *retAddr)
{
  MethodRecord *auxMethodRecord;
  byte auxByte;

#if DEBUG_METHODS
  printf("dispatch_virtual %d\n", signature);
#endif
  if (ref == JNULL)
  {
    throw_exception (nullPointerException);
    return;
  }

  auxByte = get_class_index(ref);
 LABEL_METHODLOOKUP:
  tempClassRecord = get_class_record (auxByte);
  auxMethodRecord = find_method (tempClassRecord, signature);
  if (auxMethodRecord == null)
  {
    #if SAFE
    if (auxByte == JAVA_LANG_OBJECT)
    {
      throw_exception (noSuchMethodError);
      return;
    }
    #endif
    auxByte = tempClassRecord->parentClass;
    goto LABEL_METHODLOOKUP;
  }

  if (dispatch_special (auxMethodRecord, retAddr))
  {
    if (is_synchronized(auxMethodRecord))
    {
      current_stackframe()->monitor = ref;
      enter_monitor (currentThread, ref);
    }
  }
}
Exemple #5
0
/**
 * Calls static initializer if necessary before
 * dispatching with dispatch_special().
 * @param retAddr Return bytecode address.
 * @param btAddr Backtrack bytecode address (in case
 *               static initializer is executed).
 */
void dispatch_special_checked (byte classIndex, byte methodIndex,
                               byte *retAddr, byte *btAddr)
{
  ClassRecord *classRecord;
  MethodRecord *methodRecord;
  #if DEBUG_METHODS
  printf ("dispatch_special_checked: %d, %d, %d, %d\n",
          classIndex, methodIndex, (int) retAddr, (int) btAddr);
  #endif

  // If we need to run the initializer then the real method will get called
  // later, when we re-run the current instruction.
  classRecord = get_class_record (classIndex);
  if (!is_initialized_idx (classIndex))
    if (dispatch_static_initializer (classRecord, btAddr) != EXEC_CONTINUE)
      return;
  methodRecord = get_method_record (classRecord, methodIndex);
  if(dispatch_special (methodRecord, retAddr))
  {
    if (is_synchronized(methodRecord))
    {
      if (!is_static(methodRecord))
      {

        Object *ref = (Object *)curLocalsBase[0];
        current_stackframe()->monitor = ref;
        enter_monitor (currentThread, ref);
      }
      else
      {

        Object *ref = (Object *)classRecord;
        current_stackframe()->monitor = ref;
        enter_monitor (currentThread, ref);
      }
    }
  }
}
Exemple #6
0
/** A select_handler_T read_func for itrm_in.sock.  A slave process
 * calls this when the master sends it data to be displayed.  The
 * master process never calls this.  */
static void
in_sock(struct itrm *itrm)
{
	struct string path;
	struct string delete_;
	char ch;
	int fg; /* enum term_exec */
	ssize_t bytes_read, i, p;
	unsigned char buf[ITRM_OUT_QUEUE_SIZE];

	bytes_read = safe_read(itrm->in.sock, buf, ITRM_OUT_QUEUE_SIZE);
	if (bytes_read <= 0) goto free_and_return;

qwerty:
	for (i = 0; i < bytes_read; i++)
		if (!buf[i])
			goto has_nul_byte;

	safe_hard_write(itrm->out.std, buf, bytes_read);
	return;

has_nul_byte:
	if (i) safe_hard_write(itrm->out.std, buf, i);

	i++;
	assert(ITRM_OUT_QUEUE_SIZE - i > 0);
	memmove(buf, buf + i, ITRM_OUT_QUEUE_SIZE - i);
	bytes_read -= i;
	p = 0;

#define RD(xx) {							\
		unsigned char cc;					\
									\
		if (p < bytes_read)					\
			cc = buf[p++];					\
		else if ((hard_read(itrm->in.sock, &cc, 1)) <= 0)	\
			goto free_and_return;				\
		xx = cc;						\
	}

	RD(fg);

	if (!init_string(&path)) goto free_and_return;

	while (1) {
		RD(ch);
		if (!ch) break;
		add_char_to_string(&path, ch);
	}

	if (!init_string(&delete_)) {
		done_string(&path);
		goto free_and_return;
	}

	while (1) {
		RD(ch);
		if (!ch) break;
		add_char_to_string(&delete_, ch);
	}

#undef RD

	if (!*path.source) {
		dispatch_special(delete_.source);

	} else {
		int blockh;
		unsigned char *param;
		int path_len, del_len, param_len;

		/* TODO: Should this be changed to allow TERM_EXEC_NEWWIN
		 * in a blocked terminal?  There is similar code in
		 * exec_on_terminal().  --KON, 2007 */
		if (is_blocked() && fg != TERM_EXEC_BG) {
			if (*delete_.source) unlink(delete_.source);
			goto nasty_thing;
		}

		path_len = path.length;
		del_len = delete_.length;
		param_len = path_len + del_len + 3;

		param = mem_alloc(param_len);
		if (!param) goto nasty_thing;

		param[0] = fg;
		memcpy(param + 1, path.source, path_len + 1);
		memcpy(param + 1 + path_len + 1, delete_.source, del_len + 1);

		if (fg == TERM_EXEC_FG) block_itrm();

		blockh = start_thread((void (*)(void *, int)) exec_thread,
				      param, param_len);
		mem_free(param);

		if (blockh == -1) {
			if (fg == TERM_EXEC_FG)
				unblock_itrm();

			goto nasty_thing;
		}

		if (fg == TERM_EXEC_FG) {
			set_handlers(blockh, (select_handler_T) unblock_itrm_x,
				     NULL, (select_handler_T) unblock_itrm_x,
				     (void *) (long) blockh);

		} else {
			set_handlers(blockh, close_handle, NULL, close_handle,
				     (void *) (long) blockh);
		}
	}

nasty_thing:
	done_string(&path);
	done_string(&delete_);
	assert(ITRM_OUT_QUEUE_SIZE - p > 0);
	memmove(buf, buf + p, ITRM_OUT_QUEUE_SIZE - p);
	bytes_read -= p;

	goto qwerty;

free_and_return:
	free_itrm(itrm);
}
Exemple #7
0
/**
 * Exceute the static initializer if required. Note that the ret address used
 * here is set such that the current instruction will be re-started when the
 * initialization completes.
 * @return An indication of how the VM should proceed
 */
int dispatch_static_initializer (ClassRecord *aRec, byte *retAddr)
{
  int state = get_init_state(aRec);
  ClassRecord *init = aRec;
  ClassRecord *super = get_class_record(init->parentClass);
  MethodRecord *method;
  // Are we needed?
  if (state & C_INITIALIZED) return EXEC_CONTINUE;
  // We need to initialize all of the super classes first. So we find the
  // highest one that has not been initialized and deal with that. This code
  // will then be called again and we will init the next highest and so on
  // until all of the classes in the chain are done.
  for(;;)
  {
    // find first super class that has not been initialized
    while (init != super && (get_init_state(super) & C_INITIALIZED) == 0)
    {
      init = super;
      super = get_class_record(init->parentClass);
    }
    // Do we have an initilizer if so we have found our class
    if (has_clinit (init)) break;
    // no initializer so mark as now initialized
    set_init_state (init, C_INITIALIZED);
    // If we are at the start of the list we are done
    if (init == aRec) return EXEC_CONTINUE;
    // Otherwise go do it all again
    init = aRec;
  }
  state = get_init_state(init);
  // are we already initializing ?
  if (state & C_INITIALIZING)
  {
    // Is it this thread that is doing the init?
    if (get_sync(init)->threadId == currentThread->threadId)
      return EXEC_CONTINUE;
    // No so we must retry the current instruction
    curPc = retAddr;
    sleep_thread(1);
    schedule_request(REQUEST_SWITCH_THREAD);
    return EXEC_RETRY;
  }
  #if DEBUG_METHODS
  printf ("dispatch_static_initializer: has clinit: %d, %d\n",
          (int) aRec, (int) retAddr);
  #endif
  // Static initializer is always the first method
  method = get_method_table(init);
  if ((byte *)method == get_binary_base() || method->signatureId != _6clinit_7_4_5V)
  {
    throw_new_exception (JAVA_LANG_NOSUCHMETHODERROR);
    return EXEC_EXCEPTION;
  }

  // Can we run it?
  if (!dispatch_special (method, retAddr))
    return EXEC_RETRY;
  // Mark for next time
  set_init_state(init, C_INITIALIZING);
  // and claim the monitor
  current_stackframe()->monitor = (Object *)init;
  enter_monitor (currentThread, (Object *)init);
  return EXEC_RUN;
}