diff --git a/src/classloader/classloader.go b/src/classloader/classloader.go index d1d37295..c718ca04 100644 --- a/src/classloader/classloader.go +++ b/src/classloader/classloader.go @@ -15,6 +15,7 @@ import ( "jacobin/globals" "jacobin/log" "jacobin/shutdown" + "jacobin/types" "jacobin/util" "os" "path/filepath" @@ -721,12 +722,12 @@ func (cl *Classloader) GetCountOfLoadedClasses() int { // and skips all array classes. For these latter cases or any errors, it returns "" func normalizeClassReference(ref string) string { refClassName := ref - if strings.HasPrefix(refClassName, "[L") { - refClassName = strings.TrimPrefix(refClassName, "[L") + if strings.HasPrefix(refClassName, types.RefArray) { + refClassName = strings.TrimPrefix(refClassName, types.RefArray) if strings.HasSuffix(refClassName, ";") { refClassName = strings.TrimSuffix(refClassName, ";") } - } else if strings.HasPrefix(refClassName, "[") { + } else if strings.HasPrefix(refClassName, types.Array) { refClassName = "" } return refClassName diff --git a/src/classloader/classloader_test.go b/src/classloader/classloader_test.go index bcc35994..13e0591e 100644 --- a/src/classloader/classloader_test.go +++ b/src/classloader/classloader_test.go @@ -11,6 +11,7 @@ import ( "io" "jacobin/globals" "jacobin/log" + "jacobin/types" "os" "strings" "sync" @@ -120,7 +121,7 @@ func TestNormalizingClassReference(t *testing.T) { t.Error("Unexpected normalized class reference: " + s) } - s = normalizeClassReference("[B") + s = normalizeClassReference(types.ByteArray) if s != "" { t.Error("Unexpected normalized class reference: " + s) } diff --git a/src/jvm/instantiate_test.go b/src/jvm/instantiate_test.go index da7e4238..1eff35f3 100644 --- a/src/jvm/instantiate_test.go +++ b/src/jvm/instantiate_test.go @@ -10,6 +10,7 @@ import ( "jacobin/classloader" "jacobin/globals" "jacobin/log" + "jacobin/types" "testing" ) @@ -21,7 +22,7 @@ func TestInstantiateArray(t *testing.T) { _ = log.SetLogLevel(log.WARNING) classloader.InitMethodArea() - obj, err := instantiateClass("[B") + obj, err := instantiateClass(types.ByteArray) if err != nil { t.Errorf("Got unexpected error from instantiating array: %s", err.Error()) } diff --git a/src/jvm/run.go b/src/jvm/run.go index e3f7310b..ee85e002 100644 --- a/src/jvm/run.go +++ b/src/jvm/run.go @@ -147,7 +147,7 @@ func runFrame(fs *list.List) error { } else { obj := *(f.OpStack[f.TOS].(*object.Object)) if obj.Fields != nil && len(obj.Fields) > 0 { - if obj.Fields != nil && obj.Fields[0].Ftype == "[B" { // if it's a string, just show the string + if obj.Fields != nil && obj.Fields[0].Ftype == types.ByteArray { // if it's a string, just show the string if obj.Fields[0].Fvalue == nil { stackTop = fmt.Sprintf("[]byte: ") } else { diff --git a/src/object/String.go b/src/object/String.go index 54ae9d51..1b369082 100644 --- a/src/object/String.go +++ b/src/object/String.go @@ -35,38 +35,38 @@ func NewString() *Object { // equivalent in go: runes. array := make([]byte, 10) s.Fields = append(s.Fields, - Field{Ftype: "[B", Fvalue: &array}) + Field{Ftype: types.ByteArray, Fvalue: &array}) // field 01 -- coder LATIN(=bytes, for compact strings) is 0; UTF16 is 1 - s.Fields = append(s.Fields, Field{Ftype: "B", Fvalue: int64(1)}) + s.Fields = append(s.Fields, Field{Ftype: types.Byte, Fvalue: int64(1)}) // field 02 -- string hash - s.Fields = append(s.Fields, Field{Ftype: "I", Fvalue: int64(0)}) + s.Fields = append(s.Fields, Field{Ftype: types.Int, Fvalue: int64(0)}) // field 03 -- COMPACT_STRINGS (always true for JDK >= 9) s.Fields = append(s.Fields, Field{Ftype: "XZ", Fvalue: types.JavaBoolTrue}) // field 04 -- UTF_8.INSTANCE ptr to encoder - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) // field 05 -- ISO_8859_1.INSTANCE ptr to encoder - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) // field 06 -- sun/nio/cs/US_ASCII.INSTANCE - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) // field 07 -- java/nio/charset/CodingErrorAction.REPLACE - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) // field 08 -- java/lang/String.CASE_INSENSITIVE_ORDER // points to a comparator. Will be useful to fill in later - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) - // field 09 -- hashIsZero (only true in rare case where hash is 0 - s.Fields = append(s.Fields, Field{Ftype: "Z", Fvalue: types.JavaBoolFalse}) + // field 09 -- hashIsZero (only true in rare case where hash is 0) + s.Fields = append(s.Fields, Field{Ftype: types.Bool, Fvalue: types.JavaBoolFalse}) // field 10 -- serialPersistentFields - s.Fields = append(s.Fields, Field{Ftype: "L", Fvalue: nil}) + s.Fields = append(s.Fields, Field{Ftype: types.Ref, Fvalue: nil}) return s } diff --git a/src/object/arrays.go b/src/object/arrays.go index 9b57bae0..bd4033cf 100644 --- a/src/object/arrays.go +++ b/src/object/arrays.go @@ -135,7 +135,7 @@ func MakeArrayFromRawArray(rawArray interface{}) *Object { raw := rawArray.(*[]uint8) o := MakeEmptyObject() o.Klass = nil - of := Field{Ftype: "[B", Fvalue: raw} + of := Field{Ftype: types.ByteArray, Fvalue: raw} o.Fields = append(o.Fields, of) return o } diff --git a/src/types/javaTypes.go b/src/types/javaTypes.go index c5a86d6d..3be28d00 100644 --- a/src/types/javaTypes.go +++ b/src/types/javaTypes.go @@ -15,6 +15,7 @@ const Double = "D" const Float = "F" const Int = "I" // can be either 32- or 64-bit int const Long = "J" +const Ref = "L" const Short = "S" const Array = "[" @@ -23,7 +24,6 @@ const IntArray = "[I" const FloatArray = "[F" const RefArray = "[L" const RuneArray = "[R" // used only in strings that are not compact -const Ref = "Z" // Jacobin-specific types const String = "T" diff --git a/src/util/execUtilities_test.go b/src/util/execUtilities_test.go index 29c4557b..6a3f74b6 100644 --- a/src/util/execUtilities_test.go +++ b/src/util/execUtilities_test.go @@ -7,48 +7,49 @@ package util import ( - "testing" + "jacobin/types" + "testing" ) // verify that a trailing slash in JAVA_HOME is removed func TestParseIncomingParamsFromMethType(t *testing.T) { - res := ParseIncomingParamsFromMethTypeString("(SBI)") - if len(res) != 3 { // short, byte and int all become 'I' - t.Errorf("Expected 3 parsed parameters, got %d", len(res)) - } - - if res[0] != "I" || res[1] != "I" || res[2] != "I" { - t.Errorf("Expected parse would return 3 values of 'I', got: %s%s%s", - res[0], res[1], res[2]) - } - - res = ParseIncomingParamsFromMethTypeString("(S[BI)I") - if len(res) != 3 { // short, byte and int all become 'I' - t.Errorf("Expected 3 parsed parameters, got %d", len(res)) - } - - if res[0] != "I" || res[1] != "[B" || res[2] != "I" { - t.Errorf("Expected parse would return S [B I, got: %s %s %s", - res[0], res[1], res[2]) - } - - res = ParseIncomingParamsFromMethTypeString("") - if len(res) != 0 { - t.Errorf("Expected parse would return value an empty string array, got: %s", res) - } + res := ParseIncomingParamsFromMethTypeString("(SBI)") + if len(res) != 3 { // short, byte and int all become 'I' + t.Errorf("Expected 3 parsed parameters, got %d", len(res)) + } + + if res[0] != types.Int || res[1] != types.Int || res[2] != types.Int { + t.Errorf("Expected parse would return 3 values of 'I', got: %s%s%s", + res[0], res[1], res[2]) + } + + res = ParseIncomingParamsFromMethTypeString("(S[BI)I") + if len(res) != 3 { // short, byte and int all become 'I' aka types.Int + t.Errorf("Expected 3 parsed parameters, got %d", len(res)) + } + + if res[0] != types.Int || res[1] != types.ByteArray || res[2] != types.Int { + t.Errorf("Expected parse would return S [B I, got: %s %s %s", + res[0], res[1], res[2]) + } + + res = ParseIncomingParamsFromMethTypeString("") + if len(res) != 0 { + t.Errorf("Expected parse would return value an empty string array, got: %s", res) + } } // test that pointer/refernce in the params is handled correctly // especially, that references (start with L and with ;) are correctly // parsed and represeneted in the output func TestParseIncomingReferenceParamsFromMethType(t *testing.T) { - res := ParseIncomingParamsFromMethTypeString("(LString;Ljava/lang/Integer;JJ)") - if len(res) != 4 { // short, byte and int all become 'I' - t.Errorf("Expected 4 parsed parameters, got %d", len(res)) - } - - var params string = res[0] + res[1] + res[2] + res[3] - if params != "LLJJ" { - t.Errorf("Expected param string of 'LLJJ', got: %s", params) - } + res := ParseIncomingParamsFromMethTypeString("(LString;Ljava/lang/Integer;JJ)") + if len(res) != 4 { // short, byte and int all become 'I' + t.Errorf("Expected 4 parsed parameters, got %d", len(res)) + } + + var params string = res[0] + res[1] + res[2] + res[3] + if params != "LLJJ" { + t.Errorf("Expected param string of 'LLJJ', got: %s", params) + } }