func initSuperClass(thread *Thread, class *rtc.Class) {
	if !class.IsInterface() {
		superClass := class.SuperClass()
		if superClass != nil && superClass.InitializationNotStarted() {
			initClass(thread, superClass)
		}
	}
}
示例#2
0
func _newMultiArray(counts []interface{}, arrClass *rtc.Class) *rtc.Obj {
	count := uint(counts[0].(int32))
	arr := rtc.NewArray(arrClass, count)

	if len(counts) > 1 {
		objs := arr.Refs()
		for i := range objs {
			objs[i] = _newMultiArray(counts[1:], arrClass.ComponentClass())
		}
	}

	return arr
}
func callClinit(thread *Thread, class *rtc.Class) {
	clinit := class.GetClinitMethod()
	if clinit == nil {
		clinit = rtc.ReturnMethod() // just do nothing
	}

	// exec <clinit>
	newFrame := thread.NewFrame(clinit)
	newFrame.SetOnPopAction(func() {
		// step 10
		initSucceeded(class)
	})
	thread.PushFrame(newFrame)
}
// see: jls8 12.4.2. Detailed Initialization Procedure
// http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.2
func initClass(thread *Thread, class *rtc.Class) {
	// step 1
	initCond := class.InitCond()
	initCond.L.Lock()

	// step 2 & 3
	threadPtr := uintptr(unsafe.Pointer(thread))
	isInitializing, initThreadPtr := class.IsBeingInitialized()
	if isInitializing {
		if initThreadPtr != threadPtr {
			initCond.Wait()
		} else {
			initCond.L.Unlock()
			return
		}
	}

	// step 4
	if class.IsFullyInitialized() {
		initCond.L.Unlock()
		return
	}

	// step 5
	if class.IsInitializationFailed() {
		initCond.L.Unlock()
		panic("NoClassDefFoundError") // todo
	}

	// step 6
	class.MarkBeingInitialized(threadPtr)
	initCond.L.Unlock()
	initConstantStaticFields(class)

	// step 7
	defer initSuperClass(thread, class)

	// step 8
	// todo

	// step 9 & 10
	callClinit(thread, class)

	// step 11 & 12
	// todo
}
// todo
func initConstantStaticFields(class *rtc.Class) {
	cp := class.ConstantPool()

	for _, field := range class.Fields() {
		if field.IsStatic() && field.IsFinal() {
			kValIndex := uint(field.ConstValueIndex())
			if kValIndex > 0 {
				slotId := field.SlotId()
				staticSlots := class.StaticFieldSlots()
				switch field.Descriptor() {
				case "Z", "B", "C", "S", "I":
					staticSlots[slotId] = cp.GetConstant(kValIndex).(int32)
				case "J":
					staticSlots[slotId] = cp.GetConstant(kValIndex).(int64)
				case "F":
					staticSlots[slotId] = cp.GetConstant(kValIndex).(float32)
				case "D":
					staticSlots[slotId] = cp.GetConstant(kValIndex).(float64)
				case "Ljava/lang/String;":
					staticSlots[slotId] = JString(cp.GetConstant(kValIndex).(string))
				}
			}
		}
	}
}
// step 10
func initSucceeded(class *rtc.Class) {
	initCond := class.InitCond()
	initCond.L.Lock()
	defer initCond.L.Unlock()

	class.MarkFullyInitialized()
	class.InitCond().Broadcast()
}
func (self *Thread) ThrowClassCastException(from, to *rtc.Class) {
	msg := fmt.Sprintf("%v cannot be cast to %v", from.NameJlsFormat(), to.NameJlsFormat())
	self.throwExceptionS("java/lang/ClassCastException", msg)
}