From c8e8c09a8e6b48794c552387a3f90db3d3ab4452 Mon Sep 17 00:00:00 2001
From: Volker Berlin <volker.berlin@googlemail.com>
Date: Sat, 14 Sep 2019 15:22:25 +0200
Subject: [PATCH] improve NonGC polyfill

---
 .../module/WasmCallIndirectInstruction.java       | 15 +++++++++++++--
 .../jwebassembly/module/WasmCodeBuilder.java      |  2 +-
 .../module/WasmStructInstruction.java             |  4 +++-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java
index 7335359..8a1a10c 100644
--- a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java
+++ b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java
@@ -20,10 +20,13 @@ import java.io.IOException;
 
 import javax.annotation.Nonnull;
 
+import de.inetsoftware.jwebassembly.javascript.JavaScriptSyntheticFunctionName;
 import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
 import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
 import de.inetsoftware.jwebassembly.wasm.StructOperator;
+import de.inetsoftware.jwebassembly.wasm.ValueType;
 import de.inetsoftware.jwebassembly.wasm.VariableOperator;
+import de.inetsoftware.jwebassembly.wasm.WasmOptions;
 
 /**
  * WasmInstruction for a function call.
@@ -44,6 +47,8 @@ class WasmCallIndirectInstruction extends WasmCallInstruction {
 
     private final LocaleVariableManager localVariables;
 
+    private final WasmOptions           options;
+
     /**
      * Create an instance of a function call instruction
      * 
@@ -59,11 +64,12 @@ class WasmCallIndirectInstruction extends WasmCallInstruction {
      * @param types
      *            the type manager
      */
-    WasmCallIndirectInstruction( FunctionName name, LocaleVariableManager localVariables, int javaCodePos, int lineNumber, TypeManager types ) {
+    WasmCallIndirectInstruction( FunctionName name, LocaleVariableManager localVariables, int javaCodePos, int lineNumber, TypeManager types, WasmOptions options ) {
         super( name, javaCodePos, lineNumber, types );
         this.type = types.valueOf( name.className );
         this.tempVar = localVariables.getTempVariable( type, javaCodePos, javaCodePos + 1 );
         this.localVariables = localVariables;
+        this.options = options;
     }
 
     /**
@@ -97,7 +103,12 @@ class WasmCallIndirectInstruction extends WasmCallInstruction {
             writer.writeLocal( VariableOperator.tee, tempVarIdx );
             writer.writeLocal( VariableOperator.get, tempVarIdx );
 
-            writer.writeStructOperator( StructOperator.GET, type, new NamedStorageType( type, "", "vtable" ), 0 ); // vtable is ever on position 0
+            if( options.useGC() ) {
+                writer.writeStructOperator( StructOperator.GET, type, new NamedStorageType( type, "", "vtable" ), 0 ); // vtable is ever on position 0
+            } else {
+                writer.writeConst( 0, ValueType.i32 ); // vtable is ever on position 0
+                writer.writeFunctionCall( new JavaScriptSyntheticFunctionName( "NonGC", "get_i32", () -> "(a,i) => a[i]", ValueType.anyref, ValueType.i32, null, ValueType.i32 ) );
+            }
             writer.writeLoadI32( virtualFunctionIdx * 4 );
             writer.writeVirtualFunctionCall( getFunctionName(), type );
         }
diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java
index c0617f1..2006254 100644
--- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java
+++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java
@@ -306,7 +306,7 @@ public abstract class WasmCodeBuilder {
      *            the line number in the Java source code
      */
     protected void addCallVirtualInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
-        instructions.add( new WasmCallIndirectInstruction( name, localVariables, javaCodePos, lineNumber, types ) );
+        instructions.add( new WasmCallIndirectInstruction( name, localVariables, javaCodePos, lineNumber, types, options ) );
     }
 
     /**
diff --git a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java
index a6dc4e5..c4a1caf 100644
--- a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java
+++ b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java
@@ -157,7 +157,9 @@ class WasmStructInstruction extends WasmInstruction {
             }
         }
         if( functionName != null ) { // nonGC
-            //TODO idx
+            if( fieldName != null ) {
+                writer.writeConst( idx, ValueType.i32 );
+            }
             writer.writeFunctionCall( functionName );
         } else {
             writer.writeStructOperator( op, type, fieldName, idx );