<commit_before>/* Copyright (c) 2006, <NAME>
 *
 * You may distribute this software under the terms of the license 
 * specified in the file "License"
 */

package kilim.analysis;
import static kilim.Constants.D_FIBER_LAST_ARG;
import static kilim.Constants.D_INT;
import static kilim.Constants.D_VOID;
import static kilim.Constants.FIBER_CLASS;
import static kilim.Constants.TASK_CLASS;
import static kilim.analysis.VMType.TOBJECT;
import static kilim.analysis.VMType.loadVar;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.DUP;
import static org.objectweb.asm.Opcodes.GETFIELD;
import static org.objectweb.asm.Opcodes.GOTO;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.RETURN;

import java.util.ArrayList;
import java.util.List;

import kilim.Constants;
import kilim.mirrors.Detector;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;

/**
 * This class takes the basic blocks from a MethodFlow and generates 
 * all the extra code to support continuations.  
 */

public class MethodWeaver {

    private ClassWeaver           classWeaver;

    private MethodFlow            methodFlow;

    private boolean               isPausable;

    private int                   maxVars;

    private int                   maxStack;
    
    private boolean               isSAM;

    /**
     * The last parameter to a pausable method is a Fiber ref. The rest of the
     * code doesn't know this because we do local surgery, and so is likely to
     * stomp on the corresponding local var. We need to save this in a slot
     * beyond (the original) maxLocals that is a safe haven for keeping the
     * fiberVar.
     */
    private int                   fiberVar;
    private int                   numWordsInSig;
    private ArrayList<CallWeaver> callWeavers = new ArrayList<CallWeaver>(5);

    private Detector detector;

    MethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM) {
        this.detector = detector;
        this.classWeaver = cw;
        this.methodFlow = mf;
        isPausable = mf.isPausable();
        fiberVar =  methodFlow.maxLocals;
        maxVars = fiberVar + 1;
        maxStack = methodFlow.maxStack + 1; // plus Fiber
        this.isSAM = isSAM;
        if (!mf.isAbstract()) {
            createCallWeavers();
        }
    }

    
    public void accept(ClassVisitor cv) {
        MethodFlow mf = methodFlow;
        String[] exceptions = ClassWeaver.toStringArray(mf.exceptions);
        String desc = mf.desc;
        String sig = mf.signature;
        if (mf.isPausable()) {
            if (!isSAM) {
                desc = desc.replace(")", D_FIBER_LAST_ARG);
                if (sig != null)
                    sig = sig.replace(")", D_FIBER_LAST_ARG);
            }
        }
        MethodVisitor mv = cv.visitMethod(mf.access, mf.name, desc, sig, exceptions);

        if (!mf.isAbstract()) {
            if (mf.needsWeaving()) {
                accept(mv);
            } else {
                mf.accept(mv);<commit_msg>weaver - remove varargs flag from fiber-enabled methods<commit_after>/* Copyright (c) 2006, <NAME>
 *
 * You may distribute this software under the terms of the license 
 * specified in the file "License"
 */

package kilim.analysis;
import static kilim.Constants.D_FIBER_LAST_ARG;
import static kilim.Constants.D_INT;
import static kilim.Constants.D_VOID;
import static kilim.Constants.FIBER_CLASS;
import static kilim.Constants.TASK_CLASS;
import static kilim.analysis.VMType.TOBJECT;
import static kilim.analysis.VMType.loadVar;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.DUP;
import static org.objectweb.asm.Opcodes.GETFIELD;
import static org.objectweb.asm.Opcodes.GOTO;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.RETURN;

import java.util.ArrayList;
import java.util.List;

import kilim.Constants;
import kilim.mirrors.Detector;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;

/**
 * This class takes the basic blocks from a MethodFlow and generates 
 * all the extra code to support continuations.  
 */

public class MethodWeaver {

    private ClassWeaver           classWeaver;

    private MethodFlow            methodFlow;

    private boolean               isPausable;

    private int                   maxVars;

    private int                   maxStack;
    
    private boolean               isSAM;

    /**
     * The last parameter to a pausable method is a Fiber ref. The rest of the
     * code doesn't know this because we do local surgery, and so is likely to
     * stomp on the corresponding local var. We need to save this in a slot
     * beyond (the original) maxLocals that is a safe haven for keeping the
     * fiberVar.
     */
    private int                   fiberVar;
    private int                   numWordsInSig;
    private ArrayList<CallWeaver> callWeavers = new ArrayList<CallWeaver>(5);

    private Detector detector;

    MethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM) {
        this.detector = detector;
        this.classWeaver = cw;
        this.methodFlow = mf;
        isPausable = mf.isPausable();
        fiberVar =  methodFlow.maxLocals;
        maxVars = fiberVar + 1;
        maxStack = methodFlow.maxStack + 1; // plus Fiber
        this.isSAM = isSAM;
        if (!mf.isAbstract()) {
            createCallWeavers();
        }
    }

    
    public void accept(ClassVisitor cv) {
        MethodFlow mf = methodFlow;
        String[] exceptions = ClassWeaver.toStringArray(mf.exceptions);
        String desc = mf.desc;
        String sig = mf.signature;
        int access = mf.access;
        if (mf.isPausable()) {
            access &= ~Opcodes.ACC_VARARGS;
            if (!isSAM) {
                desc = desc.replace(")", D_FIBER_LAST_ARG);
                if (sig != null)
                    sig = sig.replace(")", D_FIBER_LAST_ARG);
            }
        }
        MethodVisitor mv = cv.visitMethod(access, mf.name, desc, sig, exceptions);

        if (!mf.isAbstract()) {
            if (mf.needsWeaving()) {
                accept(mv);
            } else {
                mf.accept(mv);
{'fraction_non_alphanumeric': 0.08904918032786885, 'fraction_numerical': 0.0018360655737704918, 'mean_word_length': 2.707340787554691, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7642797', 'n_tokens_mistral': 2327, 'n_tokens_neox': 2260, 'n_words': 586}