Skip to content

Using a function as a parameter for a custom function causes ArrayIndexOutOfBoundsException #26

Open

Description

@ErzengelLichtes

Creating a custom function that accepts a function causes a java.lang.ArrayIndexOutOfBoundsException

Example Script

function test(callback as function(int)bool)
{
    if(callback(3))
    {
        print("callback success");
    }
}
//Note: The below is unnecessary but provided for completeness
test(function(a as int) as bool
{
    print("value was " ~ a);
    return true;
} as function(int)bool);

Exception in crafttweaker.log

[INITIALIZATION][CLIENT][ERROR] [crafttweaker]: Error executing {[0:crafttweaker]: testFunction.zs}: 69
java.lang.ArrayIndexOutOfBoundsException: 69
	at org.objectweb.asm.Type.getArgumentTypes(Unknown Source)
	at org.objectweb.asm.commons.LocalVariablesSorter.<init>(Unknown Source)
	at org.objectweb.asm.commons.LocalVariablesSorter.<init>(Unknown Source)
	at stanhebben.zenscript.util.MethodOutput.<init>(MethodOutput.java:26)
	at stanhebben.zenscript.ZenModule.compileScripts(ZenModule.java:114)
	at crafttweaker.runtime.CrTTweaker.loadScript(CrTTweaker.java:211)
	at crafttweaker.runtime.CrTTweaker.loadScript(CrTTweaker.java:101)
	at crafttweaker.mc1120.events.CommonEventHandler.registerRecipes(CommonEventHandler.java:69)
	at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_818_CommonEventHandler_registerRecipes_Register.invoke(.dynamic)
	at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)
	at net.minecraftforge.fml.common.eventhandler.EventBus$1.invoke(EventBus.java:144)
	at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182)
	at net.minecraftforge.registries.GameData.fireRegistryEvents(GameData.java:814)
	at net.minecraftforge.common.crafting.CraftingHelper.loadRecipes(CraftingHelper.java:624)
	at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:742)
	at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:336)
	at net.minecraft.client.Minecraft.func_71384_a(Minecraft.java:535)
	at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:3931)
	at net.minecraft.client.main.Main.main(SourceFile:123)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28)

CraftTweaker version: CraftTweaker2-1.12-4.1.15

Activity

  1. kindlich commented on Mar 13, 2019

    @kindlich
    Contributor

    ZS does not allow for functions as parameters because internally it uses different types.
    This would only be possible if you were to use a function that is registered to ZS as a functional Interface (e.g. IItemCondition)

  2. ErzengelLichtes commented on Mar 15, 2019

    @ErzengelLichtes
    Author

    Short of forking CT, can we register a functional interface using ZenClasses?

  3. kindlich commented on Mar 15, 2019

    @kindlich
    Contributor
  4. hnOsmium0001 commented on May 1, 2019

    @hnOsmium0001

    So it's like using lambda needs an interface?
    If we are allowed to define interfaces or function signatures, it seems this is possible.

  5. kindlich commented on May 1, 2019

    @kindlich
    Contributor

    You can use lambdas when you have registered a functional interface using Java Code.
    You cannot create functional interfaces from within ZS, but you can implement them (that is what a lambda is)

  6. kindlich commented on May 26, 2020

    @kindlich
    Contributor

    Hey there,

    I apologize for the late reply.
    Currently I have a rudimentary implementation for function types as parameters and members in my local dev environment.

    var myTestFun as function(string)void = function(s as string) as void {print(s);};
    myTestFun('Hello World');
    
    function myAcceptFun(consumer as function(string)void) as void {
       consumer('hello from inside myAcceptFun');
    }
    
    myAcceptFun(myTestFun);
    myAcceptFun(function(s as string) as void {print('Another thing: ' ~ s);});

    Would print

    Hello World
    hello from inside myAcceptFun
    Another thing: hello from inside myAcceptFun
    

    And

    zenClass myClass {
        var consumer as function(string)void;
        zenConstructor(consumer as function(string)void) {
            this.consumer = consumer;
        }
        function acceptString(x as string) as void {
            consumer(x);
        }
    }
    myClass(function(x as string) as void {print('inside fun: ' ~ x);}).acceptString('abc');

    Would print

    inside fun: abc
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions