diff --git a/classlib/java.base/src/main/java/de/mirkosertic/bytecoder/classlib/MemoryManager.java b/classlib/java.base/src/main/java/de/mirkosertic/bytecoder/classlib/MemoryManager.java index e274c9124..6b99f6ef9 100644 --- a/classlib/java.base/src/main/java/de/mirkosertic/bytecoder/classlib/MemoryManager.java +++ b/classlib/java.base/src/main/java/de/mirkosertic/bytecoder/classlib/MemoryManager.java @@ -246,6 +246,9 @@ public static boolean isUsedByHeapUserSpace(final int aPtrToObject) { return false; } + @Export("isUsedAsCallback") + public static native boolean isUsedAsCallback(final int aPtr); + @Export("GC") public static int GC() { return IncrementalGC(Integer.MAX_VALUE); @@ -269,7 +272,7 @@ public static int IncrementalGC(final int blockLimit) { final int theNext = Address.getIntValue(theCurrent, 4); final int theSurvivorCount = Address.getIntValue(theCurrent, 8); if (currentEpoch % theSurvivorCount == 0) { - if (!isUsedByHeap(theCurrent) && !isUsedByStack(theCurrent)) { + if (!isUsedByHeap(theCurrent) && !isUsedByStack(theCurrent) && (!isUsedAsCallback(theCurrent + 12))) { internalFree(theCurrent); freeCounter++; } else { diff --git a/core/src/main/java/de/mirkosertic/bytecoder/backend/wasm/WASMSSAASTCompilerBackend.java b/core/src/main/java/de/mirkosertic/bytecoder/backend/wasm/WASMSSAASTCompilerBackend.java index f1d12572d..39a1bd36a 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/backend/wasm/WASMSSAASTCompilerBackend.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/backend/wasm/WASMSSAASTCompilerBackend.java @@ -1408,6 +1408,7 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin theWriter.println(" runningInstanceMemory: undefined,"); theWriter.println(" exports: undefined,"); theWriter.println(" referenceTable: ['EMPTY'],"); + theWriter.println(" callbacks: [],"); theWriter.println(" filehandles: [],"); theWriter.println(); @@ -1572,6 +1573,12 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin theWriter.println(" },"); theWriter.println(); + theWriter.println(" registerCallback: function(ptr,callback) {"); + theWriter.println(" bytecoder.callbacks.push(ptr);"); + theWriter.println(" return callback;"); + theWriter.println(" },"); + theWriter.println(); + theWriter.println(" imports: {"); theWriter.println(" stringutf16: {"); theWriter.println(" isBigEndian: function() {return 1;},"); @@ -1583,14 +1590,13 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin theWriter.println(" vm: {"); theWriter.println(" newRuntimeGeneratedTypeStringMethodTypeMethodHandleObject: function() {},"); theWriter.println(" },"); - theWriter.println(" printstream: {"); - theWriter.println(" logDebug: function(caller, value) {bytecoder.logDebug(caller,value);},"); - theWriter.println(" },"); theWriter.println(" memorymanager: {"); theWriter.println(" logExceptionTextString : function(thisref, p1) {"); theWriter.println(" console.log('Exception with message : ' + bytecoder.toJSString(p1));"); theWriter.println(" },"); - + theWriter.println(" isUsedAsCallbackINT : function(thisref, ptr) {"); + theWriter.println(" return bytecoder.callbacks.includes(ptr);"); + theWriter.println(" },"); theWriter.println(" printObjectDebugInternalObjectINTINTBOOLEANBOOLEAN: function(thisref, ptr, indexAlloc, indexFree, usedByStack, usedByHeap) {"); theWriter.println(" console.log('Memory debug for ' + ptr);"); theWriter.println(" var theAllocatedBlock = ptr - 12;"); @@ -1608,7 +1614,6 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin theWriter.println(" console.log(' Memory offset +' + i + ' = ' + bytecoder.intInMemory( theAllocatedBlock + i));"); theWriter.println(" }"); theWriter.println(" }"); - theWriter.println(" },"); theWriter.println(" opaquearrays : {"); theWriter.println(" createIntArrayINT: function(thisref, p1) {"); @@ -1901,7 +1906,9 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin } final BytecodeMethod theImpl = theCallbackMethods.get(0); - theWriter.print("function ("); + theWriter.print("bytecoder.registerCallback(arg"); + theWriter.print(i); + theWriter.print(",function ("); for (int j=0;j0) { theWriter.print(","); @@ -1975,7 +1982,7 @@ public Function resolveCallsiteBootstrapFor(final BytecodeClass owningClass, fin } } - theWriter.print("}"); + theWriter.print("})"); } else { throw new IllegalStateException("Type conversion from " + theRef.name() + " is not supported!"); } diff --git a/integrationtest/src/main/java/de/mirkosertic/bytecoder/integrationtest/VueDemo.java b/integrationtest/src/main/java/de/mirkosertic/bytecoder/integrationtest/VueDemo.java index 00dfee6a4..9bbd286c9 100644 --- a/integrationtest/src/main/java/de/mirkosertic/bytecoder/integrationtest/VueDemo.java +++ b/integrationtest/src/main/java/de/mirkosertic/bytecoder/integrationtest/VueDemo.java @@ -30,23 +30,17 @@ public interface MyVueInstance extends VueInstance { void welcomemessage(final String aNewMessage); } - private static VueEventListener listener; - public static void main(final String[] args) { - // We need the static reference to avoid garbage collection for this object - // Opaque References are NOT visible to the GC, hence all references it holds also!!! - listener = new VueEventListener() { + final VueBuilder theBuilder = Vue.builder(); + theBuilder.bindToTemplateSelector("#vuetemplate"); + theBuilder.data().setProperty("welcomemessage", "hello world!"); + theBuilder.addEventListener("clicked", new VueEventListener() { @Override public void handle(final MyVueInstance instance, final ClickEvent event) { instance.welcomemessage(String.format("hello world, you have clicked. Timestamp is %s", System.currentTimeMillis())); } - }; - - final VueBuilder theBuilder = Vue.builder(); - theBuilder.bindToTemplateSelector("#vuetemplate"); - theBuilder.data().setProperty("welcomemessage", "hello world!"); - theBuilder.addEventListener("clicked", listener); + }); MyVueInstance instance = theBuilder.build(); } }