/*
   Copyright 2019 - 2022 Volker Berlin (i-net software)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
package de.inetsoftware.jwebassembly.module;

import java.io.IOException;

import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator;

/**
 * This class save a reference of THIS to a temporary variable for a later virtual caLL. The reference of THIS is used for accessing the vtable of the object.
 * 
 * @author Volker Berlin
 */
class DupThis extends WasmInstruction {

    private WasmCallIndirectInstruction virtualCall;

    private int                         tempVarSlot;

    private LocaleVariableManager       localVariables;

    /**
     * Create a instance.
     * 
     * @param virtualCall
     *            the related virtual function call.
     * @param tempVarSlot
     *            the slot of the temporary variable
     * @param localVariables
     *            the manager for local variables
     * @param javaCodePos
     *            the code position
     */
    DupThis( WasmCallIndirectInstruction virtualCall, int tempVarSlot, LocaleVariableManager localVariables, int javaCodePos ) {
        super( javaCodePos, virtualCall.getLineNumber() );
        this.virtualCall = virtualCall;
        this.tempVarSlot = tempVarSlot;
        this.localVariables = localVariables;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    Type getType() {
        return Type.DupThis;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    void writeTo( ModuleWriter writer ) throws IOException {
        if( virtualCall.isVirtual() ) {
            writer.writeLocal( VariableOperator.tee, localVariables.get( tempVarSlot, getCodePosition() ) );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    AnyType getPushValueType() {
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    int getPopCount() {
        return 0;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    AnyType[] getPopValueTypes() {
        return null;
    }
}

@@ -683,16 +683,50 @@
 ption;%0A%0A
+import javax.annotation.Nonnull;%0A%0A
 import d
@@ -767,16 +767,16 @@
 nyType;%0A
-
 import d
@@ -1064,16 +1064,29 @@
 tion %7B%0A%0A
+    @Nonnull%0A
     priv
@@ -1603,16 +1603,25 @@
 DupThis(
+ @Nonnull
  WasmCal
@@ -1868,16 +1868,16 @@
 arSlot;%0A
-
         
@@ -1913,32 +1913,211 @@
 riables;%0A    %7D%0A%0A
+    /**%0A     * Get the related virtual function call.%0A     * @return the call%0A     */%0A    @Nonnull%0A    WasmCallIndirectInstruction getValue() %7B%0A        return virtualCall;%0A    %7D%0A%0A
     /**%0A     * %7B

Add a getValue() to dup instruction