Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions src/classloader/codeCheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -712,19 +712,11 @@ func CheckCodeValidity(codePtr *[]byte, cp *CPool, maxStack int, access AccessFl
if ret == ERROR_OCCURRED {
errMsg := fmt.Sprintf("Check of %s instruction: Invalid bytecode or argument at location %d",
BytecodeNames[opcode], PC)
status := globals.GetGlobalRef().FuncThrowException(excNames.ClassFormatError, errMsg)
if status != true { // will only happen in test
globals.InitGlobals("test")
return errors.New(errMsg)
}
return errors.New(errMsg)
} else {
if ret+PC > len(code) {
errMsg := fmt.Sprintf("Invalid bytecode or argument at location %d", PC)
status := globals.GetGlobalRef().FuncThrowException(excNames.ClassFormatError, errMsg)
if status != true { // will only happen in test
globals.InitGlobals("test")
return errors.New(errMsg)
}
return errors.New(errMsg)
}
PrevPC = PC
PC += ret
Expand Down
105 changes: 103 additions & 2 deletions src/gfunction/javaUtil/javaUtilHashMap.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ func Load_Util_Hash_Map() {
GFunction: hashmapInit,
}

ghelpers.MethodSignatures["java/util/HashMap.<init>(Ljava/util/Map;)V"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.clear()V"] =
ghelpers.GMeth{
ParamSlots: 0,
Expand All @@ -64,7 +70,7 @@ func Load_Util_Hash_Map() {
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.computeIfAbsent(Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;"] =
ghelpers.MethodSignatures["java/util/HashMap.computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 2,
GFunction: ghelpers.TrapFunction,
Expand All @@ -88,18 +94,42 @@ func Load_Util_Hash_Map() {
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.equals(Ljava/lang/Object;)Z"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.entrySet()Ljava/util/Set;"] =
ghelpers.GMeth{
ParamSlots: 0,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.forEach(Ljava/util/function/BiConsumer;)V"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.get(Ljava/lang/Object;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: hashmapGet,
}

ghelpers.MethodSignatures["java/util/HashMap.getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 2,
GFunction: hashmapGetOrDefault,
}

ghelpers.MethodSignatures["java/util/HashMap.hashCode()I"] =
ghelpers.GMeth{
ParamSlots: 0,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.isEmpty()Z"] =
ghelpers.GMeth{
ParamSlots: 0,
Expand All @@ -112,7 +142,7 @@ func Load_Util_Hash_Map() {
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)V"] =
ghelpers.MethodSignatures["java/util/HashMap.merge(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 3,
GFunction: ghelpers.TrapFunction,
Expand All @@ -136,12 +166,42 @@ func Load_Util_Hash_Map() {
GFunction: hashmapPutAll,
}

ghelpers.MethodSignatures["java/util/HashMap.putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 2,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.remove(Ljava/lang/Object;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: hashmapRemove,
}

ghelpers.MethodSignatures["java/util/HashMap.remove(Ljava/lang/Object;Ljava/lang/Object;)Z"] =
ghelpers.GMeth{
ParamSlots: 2,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.replace(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"] =
ghelpers.GMeth{
ParamSlots: 2,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z"] =
ghelpers.GMeth{
ParamSlots: 3,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.replaceAll(Ljava/util/function/BiFunction;)V"] =
ghelpers.GMeth{
ParamSlots: 1,
GFunction: ghelpers.TrapFunction,
}

ghelpers.MethodSignatures["java/util/HashMap.size()I"] =
ghelpers.GMeth{
ParamSlots: 0,
Expand Down Expand Up @@ -285,6 +345,47 @@ func hashmapGet(params []interface{}) interface{} {
return value
}

// Get a hash map entry. If it is not present, return the default value.
func hashmapGetOrDefault(params []interface{}) interface{} {
if len(params) < 3 {
errMsg := "hashmapGetOrDefault: Requires 3 parameters: HashMap, key, and default value"
return ghelpers.GetGErrBlk(excNames.IllegalArgumentException, errMsg)
}

this, ok := params[0].(*object.Object)
if !ok || this == nil {
errMsg := "hashmapGetOrDefault: The first parameter is not an object"
return ghelpers.GetGErrBlk(excNames.ClassCastException, errMsg)
}

if *stringPool.GetStringPointer(this.KlassName) != classNameHashMap {
errMsg := "hashmapGetOrDefault: The object is not a HashMap"
return ghelpers.GetGErrBlk(excNames.IllegalArgumentException, errMsg)
}

// Extract the key.
key, ok := _getKey(params[1])
if !ok {
return key
}

// Get the current hash map.
fld := this.FieldTable[fieldNameMap]
hm, ok := fld.Fvalue.(types.DefHashMap)
if !ok {
errMsg := "hashmapGetOrDefault: The HashMap is not present"
return ghelpers.GetGErrBlk(excNames.IllegalArgumentException, errMsg)
}

// Retrieve the field associated with the key
value, exists := hm[key]
if !exists {
return params[2]
}

return value
}

// Remove a hash map entry. Return the removed value or nil if there is not one that matches the key.
func hashmapRemove(params []interface{}) interface{} {
hashmapMutex.Lock()
Expand Down
30 changes: 30 additions & 0 deletions src/gfunction/javaUtil/javaUtilHashMap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,33 @@ func TestHashMap_ErrorPaths(t *testing.T) {
}
}
}

func TestHashMap_GetOrDefault(t *testing.T) {
globals.InitStringPool()

hm := newHashMapObj()
hmInit(t, hm)

k := strKey("key")
v := object.StringObjectFromGoString("value")
d := object.StringObjectFromGoString("default")

// 1. Key not present, returns default
res := hashmapGetOrDefault([]interface{}{hm, k, d})
if res != d {
t.Fatalf("expected default value, got %v", res)
}

// 2. Key present, returns value
_ = hashmapPut([]interface{}{hm, k, v})
res = hashmapGetOrDefault([]interface{}{hm, k, d})
if res != v {
t.Fatalf("expected stored value, got %v", res)
}

// 3. Error: missing parameters
err := hashmapGetOrDefault([]interface{}{hm, k})
if geb, ok := err.(*ghelpers.GErrBlk); !ok || geb.ExceptionType != excNames.IllegalArgumentException {
t.Fatalf("expected IllegalArgumentException for missing params")
}
}
Loading
Loading