bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) {
  ConstantPool* constants = method()->constants();
  int ilimit = constants->length();
  Bytecodes::Code code = raw_code();

  ConstantPoolCache* cache = NULL;
  if (Bytecodes::uses_cp_cache(code)) {
    bool okay = true;
    switch (code) {
    case Bytecodes::_fast_aldc:
    case Bytecodes::_fast_aldc_w:
      okay = check_obj_index(i, cp_index, st);
      break;
    case Bytecodes::_invokedynamic:
      okay = check_invokedynamic_index(i, cp_index, st);
      break;
    default:
      okay = check_cp_cache_index(i, cp_index, st);
      break;
    }
    if (!okay) return false;
  }


  // check cp index
  if (cp_index >= 0 && cp_index < ilimit) {
    if (WizardMode)  st->print(" cp[%d]", cp_index);
    return true;
  }

  st->print_cr(" CP[%d] not in CP", cp_index);
  return false;
}
static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section,
                             ConstantPool &CP) {
  if (!CP.empty()) {
    Streamer.SwitchSection(Section);
    CP.emitEntries(Streamer);
  }
}
Example #3
0
void InterpretTest::gcTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("GCTest", pool);
	const char code[] = 
	{
		PUSH, 0x00, 0x00,
		STORE_LOCAL, 0x00,
		PUSH, 0x01, 0x00, //label1
		LOAD_LOCAL, 0x00,
		SUB,
		IF_GE, 0x0D,//if(i < 1000)
		PUSH, 0x01, 0x00,
		NEW_ARRAY,
		STORE_LOCAL, 0x01,
		LOAD_LOCAL, 0x00,
		INC,
		STORE_LOCAL, 0x00,
		JMP, -21,
		RET_VOID
	};
	Method * m = initMethod("gcTest", code, sizeof(code), 0, 2, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 0;
	pool->addItem(&i, INT_CONST);//0
	i.value = 1000;
	pool->addItem(&i, INT_CONST);//1
	cls->addMethod(m);
	cl.addClass(cls);
	instance.run(cls->getName().c_str(), m->getName().c_str());
}
Example #4
0
void InterpretTest::localsTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("LocalsTest", pool);
	const char code[] = 
	{
		PUSH, 0x00, 0x00,
		STORE_LOCAL, 0x00,
		PUSH, 0x01, 0x00,
		STORE_LOCAL, 0x01,
		LOAD_LOCAL, 0x00,
		LOAD_LOCAL, 0x01,
		ADD,
		RET
	};
	Method * m = initMethod("localsTest", code, sizeof(code), 0, 2, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 20;
	pool->addItem(&i, INT_CONST);
	i.value = 30;
	pool->addItem(&i, INT_CONST);
	cls->addMethod(m);
	cl.addClass(cls);
	assert(50 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
Example #5
0
void InterpretTest::aritmeticTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("AritmeticTest", pool);
	const char code[] = 
	{
		PUSH, 0x00, 0x00,
		PUSH, 0x01, 0x00,
		ADD,
		PUSH, 0x00, 0x00,
		SUB,
		PUSH, 0x00, 0x00,
		MUL,
		PUSH, 0x00, 0x00,
		DIV,
		INC,
		DEC,
		RET
	};
	Method * m = initMethod("aritmeticTest", code, sizeof(code), 0, 0, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 20;
	pool->addItem(&i, INT_CONST);
	i.value = 30;
	pool->addItem(&i, INT_CONST);
	cls->addMethod(m);
	cl.addClass(cls);
	assert(30 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
  //interpreteur put fast_invoke_virtual_final not only for 
  //static methods but also for final methods of Object class!
  void check_uncommon_or_static_method(int index JVM_TRAPS) {
    ConstantPool cp = method()->constants();

    if (!cp.tag_at(index).is_resolved_final_uncommon_interface_method()) {
      check_static(index JVM_CHECK);
    }
  }
Example #7
0
oop Bytecode_loadconstant::resolve_constant(TRAPS) const {
  assert(_method.not_null(), "must supply method to resolve constant");
  int index = raw_index();
  ConstantPool* constants = _method->constants();
  if (has_cache_index()) {
    return constants->resolve_cached_constant_at(index, THREAD);
  } else {
    return constants->resolve_constant_at(index, THREAD);
  }
}
Example #8
0
void InterpretTest::arrayTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("ArrayTest", pool);
	const char code[] = 
	{
		PUSH, 0x01, 0x00,
		NEW_ARRAY, // a = array[10]
		STORE_LOCAL, 0x00,
		PUSH, 0x00, 0x00,
		STORE_LOCAL, 0x01, // i = 0
		LOAD_LOCAL, 0x01, //label1
		PUSH, 0x01, 0x00,
		SUB,
		IF_GE, 0x0C,//if(i < 10)
		LOAD_LOCAL, 0x01,
		DUP, DUP,
		LOAD_LOCAL, 0x00,
		STORE_ARRAY, //a[i] = i
		INC,
		STORE_LOCAL, 0x01,
		JMP, -20, //jmp label1
		PUSH, 0x00, 0x00,
		PUSH, 0x00, 0x00,
		STORE_LOCAL, 0x01,
		STORE_LOCAL, 0x02,
		LOAD_LOCAL, 0x01, //label2
		PUSH, 0x01, 0x00,
		SUB,
		IF_GE, 17,//if(i < 10)
		LOAD_LOCAL, 0x01,
		LOAD_LOCAL, 0x00,
		LOAD_ARRAY, 
		LOAD_LOCAL, 0x02,
		ADD,  
		STORE_LOCAL, 0x02, //sum += a[i]
		LOAD_LOCAL, 0x01,
		INC,
		STORE_LOCAL, 0x01,
		JMP, -25, //jmp label2
		LOAD_LOCAL, 0x02,
		RET
	};
	Method * m = initMethod("arrayTest", code, sizeof(code), 0, 3, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 0;
	pool->addItem(&i, INT_CONST);//0
	i.value = 10;
	pool->addItem(&i, INT_CONST);//1
	cls->addMethod(m);
	cl.addClass(cls);
	assert(45 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
Example #9
0
void InterpretTest::jumpTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("JumpTest", pool);
	const char code[] = 
	{
		JMP, 0x01,
		RET_VOID, //skipped
		PUSH, 0x01, 0x00,
		IF_EQ, 0x01,
		RET_VOID, //skipped
		PUSH, 0x00, 0x00,
		IF_NE, 0x01,
		RET_VOID, //skipped
		PUSH, 0x02, 0x00,
		IF_LT, 0x01,
		RET_VOID, //skipped
		PUSH, 0x00, 0x00,
		IF_GT, 0x01,
		RET_VOID, //skipped
		PUSH, 0x00, 0x00,
		PUSH, 0x00, 0x00,
		IF_LE, 0x02,
		IF_GE, 0x01,
		RET_VOID, //skipped
		PUSH, 0x00, 0x00,
		INC,
		PUSH, 0x00, 0x00,
		INC,
		CMP_EQ,
		IF_EQ, 0x01,
		RET_VOID,
		PUSH, 0x00, 0x00,
		PUSH, 0x0, 0x00,
		CMP_NE,
		IF_NE, 0x01,
		RET_VOID,
		PUSH, 0x00, 0x00,
		RET
	};
	Method * m = initMethod("jumpTest", code, sizeof(code), 0, 0, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 1;
	pool->addItem(&i, INT_CONST);
	i.value = 0;
	pool->addItem(&i, INT_CONST);
	i.value = -1;
	pool->addItem(&i, INT_CONST);
	cls->addMethod(m);
	cl.addClass(cls);
	assert(1 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
bool BytecodePrinter::check_obj_index(int i, int& cp_index, outputStream* st) {
  ConstantPool* constants = method()->constants();
  i -= ConstantPool::CPCACHE_INDEX_TAG;

  if (i >= 0 && i < constants->resolved_references()->length()) {
     cp_index = constants->object_to_cp_index(i);
     return true;
  } else {
    st->print_cr(" not in OBJ[*]?", i);
  return false;
}
}
void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) {
  ConstantPool* constants = method()->constants();
  constantTag tag = constants->tag_at(i);

  bool has_klass = true;

  switch (tag.value()) {
  case JVM_CONSTANT_InterfaceMethodref:
  case JVM_CONSTANT_Methodref:
  case JVM_CONSTANT_Fieldref:
    break;
  case JVM_CONSTANT_NameAndType:
  case JVM_CONSTANT_InvokeDynamic:
    has_klass = false;
    break;
  default:
    st->print_cr(" bad tag=%d at %d", tag.value(), i);
    return;
  }

  Symbol* name = constants->uncached_name_ref_at(i);
  Symbol* signature = constants->uncached_signature_ref_at(i);
  const char* sep = (tag.is_field() ? "/" : "");
  if (has_klass) {
    Symbol* klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i));
    st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
  } else {
    if (tag.is_invoke_dynamic()) {
      int bsm = constants->invoke_dynamic_bootstrap_method_ref_index_at(i);
      st->print(" bsm=%d", bsm);
    }
    st->print_cr(" %d <%s%s%s>", i, name->as_C_string(), sep, signature->as_C_string());
  }
}
Example #12
0
void InterpretTest::callTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("CallTest", pool);
	const char code1[] = 
	{
		RET_VOID
	};
	const char code2[] = 
	{
		PUSH, 0x00, 0x00,
		RET
	};
	const char code[] =
	{
		CALL, 0x01, 0x00, 0x02, 0x00, //ClassRef na pozici 1, MethodRef na pozici 2
		CALL, 0x01, 0x00, 0x03, 0x00, //ClassRef na pozici 1, MethodRef na pozici 3
		RET
	};
	Method * m = initMethod("callTest", code, sizeof(code), 0, 0, 0);
	Method * m1 = initMethod("returnVoid", code1, sizeof(code1), 0, 0, 0);
	Method * m2 = initMethod("returnInt", code2, sizeof(code2), 0, 0, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 1;
	pool->addItem(&i, INT_CONST);//0
	ClassRef cr;
	memset(cr.name, 0x00, IDENTIFIER_LENGTH);
	sprintf(cr.name, "%s", cls->getName().c_str());
	pool->addItem(&cr, CLASS_REF);//1
	MethodRef mr;
	sprintf(mr.name, "%s", m1->getName().c_str());
	mr.params = 0;
	pool->addItem(&mr, METHOD_REF);//2
	sprintf(mr.name, "%s", m2->getName().c_str());
	pool->addItem(&mr, METHOD_REF);//3
	cls->addMethod(m);
	cls->addMethod(m1);
	cls->addMethod(m2);
	cl.addClass(cls);
	assert(1 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
static void switchover_constant_pool(BytecodeConstantPool* bpool,
    InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) {

  if (new_methods->length() > 0) {
    ConstantPool* cp = bpool->create_constant_pool(CHECK);
    if (cp != klass->constants()) {
      klass->class_loader_data()->add_to_deallocate_list(klass->constants());
      klass->set_constants(cp);
      cp->set_pool_holder(klass);

      for (int i = 0; i < new_methods->length(); ++i) {
        new_methods->at(i)->set_constants(cp);
      }
      for (int i = 0; i < klass->methods()->length(); ++i) {
        Method* mo = klass->methods()->at(i);
        mo->set_constants(cp);
      }
    }
  }
}
Example #14
0
ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
  if (_entries.length() == 0) {
    return _orig;
  }

  ConstantPool* cp = ConstantPool::allocate(
      _orig->pool_holder()->class_loader_data(),
      _orig->length() + _entries.length(), CHECK_NULL);

  cp->set_pool_holder(_orig->pool_holder());
  _orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);

  for (int i = 0; i < _entries.length(); ++i) {
    BytecodeCPEntry entry = _entries.at(i);
    int idx = i + _orig->length();
    switch (entry._tag) {
      case BytecodeCPEntry::UTF8:
        entry._u.utf8->increment_refcount();
        cp->symbol_at_put(idx, entry._u.utf8);
        break;
      case BytecodeCPEntry::KLASS:
        cp->unresolved_klass_at_put(
            idx, cp->symbol_at(entry._u.klass));
        break;
      case BytecodeCPEntry::STRING:
        cp->unresolved_string_at_put(
            idx, cp->symbol_at(entry._u.string));
        break;
      case BytecodeCPEntry::NAME_AND_TYPE:
        cp->name_and_type_at_put(idx,
            entry._u.name_and_type.name_index,
            entry._u.name_and_type.type_index);
        break;
      case BytecodeCPEntry::METHODREF:
        cp->method_at_put(idx,
            entry._u.methodref.class_index,
            entry._u.methodref.name_and_type_index);
        break;
      default:
        ShouldNotReachHere();
    }
  }
  return cp;
}
bool BytecodePrinter::check_cp_cache_index(int i, int& cp_index, outputStream* st) {
  ConstantPool* constants = method()->constants();
  int ilimit = constants->length(), climit = 0;
  Bytecodes::Code code = raw_code();

  ConstantPoolCache* cache = constants->cache();
  // If rewriter hasn't run, the index is the cp_index
  if (cache == NULL) {
    cp_index = i;
    return true;
  }
  //climit = cache->length();  // %%% private!
  size_t size = cache->size() * HeapWordSize;
  size -= sizeof(ConstantPoolCache);
  size /= sizeof(ConstantPoolCacheEntry);
  climit = (int) size;

#ifdef ASSERT
  {
    const int CPCACHE_INDEX_TAG = ConstantPool::CPCACHE_INDEX_TAG;
    if (i >= CPCACHE_INDEX_TAG && i < climit + CPCACHE_INDEX_TAG) {
      i -= CPCACHE_INDEX_TAG;
    } else {
      st->print_cr(" CP[%d] missing bias?", i);
      return false;
    }
  }
#endif //ASSERT
  if (i >= 0 && i < climit) {
    cp_index = cache->entry_at(i)->constant_pool_index();
  } else {
    st->print_cr(" not in CP[*]?", i);
      return false;
    }
  return true;
  }
Example #16
0
void InterpretTest::consoleTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("ConsoleTest", pool);
	const char code[] = 
	{
		PUSH, 0x00, 0x00,
		CALL, 0x01, 0x00, 0x02, 0x00, //console.print(20)
		CALL, 0x01, 0x00, 0x03, 0x00, //line = console.readLine()
		CALL, 0x01, 0x00, 0x02, 0x00, //console.print(line)
		CALL, 0x01, 0x00, 0x04, 0x00, //i = console.readInt()
		CALL, 0x01, 0x00, 0x02, 0x00, //console.print(i)
		CALL, 0x01, 0x00, 0x05, 0x00, //i = console.readReal()
		CALL, 0x01, 0x00, 0x02, 0x00, //console.print(i)
		RET_VOID
	};
	Method * m = initMethod("consoleTest", code, sizeof(code), 0, 2, 0);
	ClassLoader cl("");
	Interpret instance(&cl);
	IntConst i;
	i.value = 20;
	pool->addItem(&i, INT_CONST);//0
	ClassRef cr;
	sprintf(cr.name, "%s", CONSOLE_CLASS);//1
	pool->addItem(&cr, CLASS_REF);
	MethodRef mr;
	sprintf(mr.name, "print");
	mr.params = 1;
	pool->addItem(&mr, METHOD_REF);//2
	sprintf(mr.name, "readLine");
	mr.params = 0;
	pool->addItem(&mr, METHOD_REF);//3
	sprintf(mr.name, "readInt");
	mr.params = 0;
	pool->addItem(&mr, METHOD_REF);//4
	sprintf(mr.name, "readReal");
	mr.params = 0;
	pool->addItem(&mr, METHOD_REF);//5
	cls->addMethod(m);
	cl.addClass(cls);
	instance.run(cls->getName().c_str(), m->getName().c_str());
}
void BytecodePrinter::print_attributes(int bci, outputStream* st) {
  // Show attributes of pre-rewritten codes
  Bytecodes::Code code = Bytecodes::java_code(raw_code());
  // If the code doesn't have any fields there's nothing to print.
  // note this is ==1 because the tableswitch and lookupswitch are
  // zero size (for some reason) and we want to print stuff out for them.
  if (Bytecodes::length_for(code) == 1) {
    st->cr();
    return;
  }

  switch(code) {
    // Java specific bytecodes only matter.
    case Bytecodes::_bipush:
      st->print_cr(" " INT32_FORMAT, get_byte());
      break;
    case Bytecodes::_sipush:
      st->print_cr(" " INT32_FORMAT, get_short());
      break;
    case Bytecodes::_ldc:
      if (Bytecodes::uses_cp_cache(raw_code())) {
        print_constant(get_index_u1_cpcache(), st);
      } else {
        print_constant(get_index_u1(), st);
      }
      break;

    case Bytecodes::_ldc_w:
    case Bytecodes::_ldc2_w:
      if (Bytecodes::uses_cp_cache(raw_code())) {
        print_constant(get_index_u2_cpcache(), st);
      } else {
        print_constant(get_index_u2(), st);
      }
      break;

    case Bytecodes::_iload:
    case Bytecodes::_lload:
    case Bytecodes::_fload:
    case Bytecodes::_dload:
    case Bytecodes::_aload:
    case Bytecodes::_istore:
    case Bytecodes::_lstore:
    case Bytecodes::_fstore:
    case Bytecodes::_dstore:
    case Bytecodes::_astore:
      st->print_cr(" #%d", get_index_special());
      break;

    case Bytecodes::_iinc:
      { int index = get_index_special();
        jint offset = is_wide() ? get_short(): get_byte();
        st->print_cr(" #%d " INT32_FORMAT, index, offset);
      }
      break;

    case Bytecodes::_newarray: {
        BasicType atype = (BasicType)get_index_u1();
        const char* str = type2name(atype);
        if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) {
          assert(false, "Unidentified basic type");
        }
        st->print_cr(" %s", str);
      }
      break;
    case Bytecodes::_anewarray: {
        int klass_index = get_index_u2();
        ConstantPool* constants = method()->constants();
        Symbol* name = constants->klass_name_at(klass_index);
        st->print_cr(" %s ", name->as_C_string());
      }
      break;
    case Bytecodes::_multianewarray: {
        int klass_index = get_index_u2();
        int nof_dims = get_index_u1();
        ConstantPool* constants = method()->constants();
        Symbol* name = constants->klass_name_at(klass_index);
        st->print_cr(" %s %d", name->as_C_string(), nof_dims);
      }
      break;

    case Bytecodes::_ifeq:
    case Bytecodes::_ifnull:
    case Bytecodes::_iflt:
    case Bytecodes::_ifle:
    case Bytecodes::_ifne:
    case Bytecodes::_ifnonnull:
    case Bytecodes::_ifgt:
    case Bytecodes::_ifge:
    case Bytecodes::_if_icmpeq:
    case Bytecodes::_if_icmpne:
    case Bytecodes::_if_icmplt:
    case Bytecodes::_if_icmpgt:
    case Bytecodes::_if_icmple:
    case Bytecodes::_if_icmpge:
    case Bytecodes::_if_acmpeq:
    case Bytecodes::_if_acmpne:
    case Bytecodes::_goto:
    case Bytecodes::_jsr:
      st->print_cr(" %d", bci + get_short());
      break;

    case Bytecodes::_goto_w:
    case Bytecodes::_jsr_w:
      st->print_cr(" %d", bci + get_int());
      break;

    case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;

    case Bytecodes::_tableswitch:
      { align();
        int  default_dest = bci + get_int();
        int  lo           = get_int();
        int  hi           = get_int();
        int  len          = hi - lo + 1;
        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
        for (int i = 0; i < len; i++) {
          dest[i] = bci + get_int();
        }
        st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
                      default_dest, lo, hi);
        int first = true;
        for (int ll = lo; ll <= hi; ll++, first = false)  {
          int idx = ll - lo;
          const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
                                       ", %d:" INT32_FORMAT " (delta: %d)";
          st->print(format, ll, dest[idx], dest[idx]-bci);
        }
        st->cr();
      }
      break;
    case Bytecodes::_lookupswitch:
      { align();
        int  default_dest = bci + get_int();
        int  len          = get_int();
        jint* key         = NEW_RESOURCE_ARRAY(jint, len);
        jint* dest        = NEW_RESOURCE_ARRAY(jint, len);
        for (int i = 0; i < len; i++) {
          key [i] = get_int();
          dest[i] = bci + get_int();
        };
        st->print(" %d %d ", default_dest, len);
        bool first = true;
        for (int ll = 0; ll < len; ll++, first = false)  {
          const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
                                       ", " INT32_FORMAT ":" INT32_FORMAT ;
          st->print(format, key[ll], dest[ll]);
        }
        st->cr();
      }
      break;

    case Bytecodes::_putstatic:
    case Bytecodes::_getstatic:
    case Bytecodes::_putfield:
    case Bytecodes::_getfield:
      print_field_or_method(get_index_u2_cpcache(), st);
      break;

    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokestatic:
      print_field_or_method(get_index_u2_cpcache(), st);
      break;

    case Bytecodes::_invokeinterface:
      { int i = get_index_u2_cpcache();
        int n = get_index_u1();
        get_byte();            // ignore zero byte
        print_field_or_method(i, st);
      }
      break;

    case Bytecodes::_invokedynamic:
      print_field_or_method(get_index_u4(), st);
      break;

    case Bytecodes::_new:
    case Bytecodes::_checkcast:
    case Bytecodes::_instanceof:
      { int i = get_index_u2();
        ConstantPool* constants = method()->constants();
        Symbol* name = constants->klass_name_at(i);
        st->print_cr(" %d <%s>", i, name->as_C_string());
      }
      break;

    case Bytecodes::_wide:
      // length is zero not one, but printed with no more info.
      break;

    default:
      ShouldNotReachHere();
      break;
  }
}
void BytecodePrinter::print_constant(int i, outputStream* st) {
  int orig_i = i;
  if (!check_index(orig_i, i, st))  return;

  ConstantPool* constants = method()->constants();
  constantTag tag = constants->tag_at(i);

  if (tag.is_int()) {
    st->print_cr(" " INT32_FORMAT, constants->int_at(i));
  } else if (tag.is_long()) {
    st->print_cr(" " INT64_FORMAT, constants->long_at(i));
  } else if (tag.is_float()) {
    st->print_cr(" %f", constants->float_at(i));
  } else if (tag.is_double()) {
    st->print_cr(" %f", constants->double_at(i));
  } else if (tag.is_string()) {
    const char* string = constants->string_at_noresolve(i);
    st->print_cr(" %s", string);
  } else if (tag.is_klass()) {
    st->print_cr(" %s", constants->resolved_klass_at(i)->external_name());
  } else if (tag.is_unresolved_klass()) {
    st->print_cr(" <unresolved klass at %d>", i);
  } else if (tag.is_method_type()) {
    int i2 = constants->method_type_index_at(i);
    st->print(" <MethodType> %d", i2);
    print_symbol(constants->symbol_at(i2), st);
  } else if (tag.is_method_handle()) {
    int kind = constants->method_handle_ref_kind_at(i);
    int i2 = constants->method_handle_index_at(i);
    st->print(" <MethodHandle of kind %d>", kind, i2);
    print_field_or_method(-i, i2, st);
  } else {
    st->print_cr(" bad tag=%d at %d", tag.value(), i);
  }
}
Example #19
0
void InterpretTest::callDynamicTest()
{
	ConstantPool * pool = new ConstantPool();
	Class * cls = initClass("Counter", pool);
	cls->addField("counter");
	const char code1[] = 
	{
		LOAD_LOCAL, 0x00, // PUSH this
		LOAD, 0x06, 0x00, //PUSH this[0]
		LOAD_LOCAL, 0x01, // PUSH value
		ADD,  // this[0] + value
		LOAD_LOCAL, 0x00, // PUSH this
		STORE, 0x06, 0x00, // this[0] = this[0] + value
		RET_VOID
	};
	const char code2[] = 
	{
		LOAD_LOCAL, 0x00, // PUSH this
		LOAD, 0x06, 0x00, //PUSH this[0]
		RET
	};
	const char code3[] = 
	{
		PUSH, 0x04, 0x00, // PUSH 0
		LOAD_LOCAL, 0x00, // PUSH this
		STORE, 0x06, 0x00,  // this[0] = 0
		RET_VOID
	};
	const char code[] =
	{
		NEW, 0x00, 0x00, //new Counter
		DUP, STORE_LOCAL, 0x00, //a = new Counter
		CALL_DYNAMIC, 0x03, 0x00, //a.init
		LOAD_LOCAL, 0x00,
		PUSH, 0x05, 0x00, //PUSH 3
		CALL_DYNAMIC, 0x01, 0x00, //a.increase(3)
		LOAD_LOCAL, 0x00,
		CALL_DYNAMIC, 0x02, 0x00, //a.getValue
		RET
	};
	Method * m = initMethod("callTest", code, sizeof(code), 0, 1, 0);
	Method * m1 = initMethod("increase", code1, sizeof(code1), 2, 0, 1);
	Method * m2 = initMethod("getValue", code2, sizeof(code2), 1, 1, 1);
	Method * m3 = initMethod("init", code3, sizeof(code3), 1, 1, 1);
	ClassLoader cl("");
	Interpret instance(&cl);
	ClassRef cr;
	memset(cr.name, 0x00, IDENTIFIER_LENGTH);
	sprintf(cr.name, "%s", cls->getName().c_str());
	pool->addItem(&cr, CLASS_REF); //0
	MethodRef mr;
	mr.params = m1->getParamCount();
	sprintf(mr.name, "%s", m1->getName().c_str());
	pool->addItem(&mr, METHOD_REF); //1
	mr.params = m2->getParamCount();
	sprintf(mr.name, "%s", m2->getName().c_str());
	pool->addItem(&mr, METHOD_REF); //2
	mr.params = m3->getParamCount();
	sprintf(mr.name, "%s", m3->getName().c_str());
	pool->addItem(&mr, METHOD_REF); //3
	IntConst i;
	i.value = 0;
	pool->addItem(&i, INT_CONST); //4
	i.value = 3;
	pool->addItem(&i, INT_CONST); //5
	FieldRef fr;
	memset(fr.name, 0x00, IDENTIFIER_LENGTH);
	sprintf(fr.name, "counter");
	pool->addItem(&fr, FIELD_REF); //6
	cls->addMethod(m);
	cls->addMethod(m1);
	cls->addMethod(m2);
	cls->addMethod(m3);
	cl.addClass(cls);
	assert(3 == instance.run(cls->getName().c_str(), m->getName().c_str()));
}
Struct_CP_Table::Struct_CP_Table(ConstantPool const &constantPool)
{
    CPMaker v(constants);
    constantPool.accept(v);
}