<commit_before>package soot.dexpler;

import java.util.Map;

import soot.Body;
import soot.BodyTransformer;
import soot.Local;
import soot.Trap;
import soot.Unit;
import soot.javaToJimple.LocalGenerator;
import soot.jimple.CaughtExceptionRef;
import soot.jimple.IdentityStmt;
import soot.jimple.Jimple;
import soot.jimple.Stmt;

/**
 * Transformer to ensure that all exception handlers pull the exception object.
 * In other words, if an exception handler must always have a unit like
 * 
 * 		$r10 = @caughtexception
 * 
 * This is especially important if the dex code is later to be translated into
 * Java bytecode. If no one ever accesses the exception object, it will reside
 * on the stack forever, potentially leading to mismatching stack heights.
 * 
 * @author <NAME>
 *
 */
public class DexTrapStackFixer extends BodyTransformer {

	public static DexTrapStackFixer v() {
		return new DexTrapStackFixer();
	}
	
	@Override
	protected void internalTransform(Body b, String phaseName,
			Map<String, String> options) {
		for (Trap t : b.getTraps()) {
			// If the first statement already catches the exception, we're fine
			if (isCaughtExceptionRef(t.getHandlerUnit()))
				continue;
			
			// Add the exception reference
			Local l = new LocalGenerator(b).generateLocal(t.getException().getType());
			Stmt caughtStmt = Jimple.v().newIdentityStmt(l, Jimple.v().newCaughtExceptionRef());
			b.getUnits().insertBefore(caughtStmt, t.getHandlerUnit());
		}
	}<commit_msg>yet another fix for APKs that do not pull exception references<commit_after>package soot.dexpler;

import java.util.Map;

import soot.Body;
import soot.BodyTransformer;
import soot.Local;
import soot.Trap;
import soot.Unit;
import soot.javaToJimple.LocalGenerator;
import soot.jimple.CaughtExceptionRef;
import soot.jimple.IdentityStmt;
import soot.jimple.Jimple;
import soot.jimple.Stmt;

/**
 * Transformer to ensure that all exception handlers pull the exception object.
 * In other words, if an exception handler must always have a unit like
 * 
 * 		$r10 = @caughtexception
 * 
 * This is especially important if the dex code is later to be translated into
 * Java bytecode. If no one ever accesses the exception object, it will reside
 * on the stack forever, potentially leading to mismatching stack heights.
 * 
 * @author <NAME>
 *
 */
public class DexTrapStackFixer extends BodyTransformer {

	public static DexTrapStackFixer v() {
		return new DexTrapStackFixer();
	}
	
	@Override
	protected void internalTransform(Body b, String phaseName,
			Map<String, String> options) {
		for (Trap t : b.getTraps()) {
			// If the first statement already catches the exception, we're fine
			if (isCaughtExceptionRef(t.getHandlerUnit()))
				continue;
			
			// Add the exception reference
			Local l = new LocalGenerator(b).generateLocal(t.getException().getType());
			Stmt caughtStmt = Jimple.v().newIdentityStmt(l, Jimple.v().newCaughtExceptionRef());
			b.getUnits().add(caughtStmt);
			b.getUnits().add(Jimple.v().newGotoStmt(t.getHandlerUnit()));
			t.setHandlerUnit(caughtStmt);
		}
	}
{'fraction_non_alphanumeric': 0.09647979139504563, 'fraction_numerical': 0.001303780964797914, 'mean_word_length': 4.470588235294118, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '1444856', 'n_tokens_mistral': 1019, 'n_tokens_neox': 911, 'n_words': 295}