package org.jerlang.erts.emulator.op; import java.util.ArrayList; import org.jerlang.FunctionSignature; import org.jerlang.Module; import org.jerlang.Process; import org.jerlang.erts.Erlang; import org.jerlang.erts.emulator.Instruction; import org.jerlang.exception.ThrowException; import org.jerlang.type.Integer; import org.jerlang.type.List; import org.jerlang.type.Term; /** * Call the bif Bif with the arguments Arg1 and Arg2, * and store the result in Reg. * On failure jump to Lbl. * Do a garbage collection if necessary to allocate space on the heap * for the result (saving Live number of X registers). * * Arguments: * 1. Lbl * 2. Live * 3. Bif * 4. Arg1 * 5. Arg2 * 6. Reg */ public class GcBif2 { public static Term execute(Process process, Module m, Instruction i, List params) throws ThrowException { Term bif = i.arg(2); // 1 Term arg1 = i.arg(3); // {y,0} Term arg2 = i.arg(4); // {x,0} Term reg = i.arg(5); // {x,0} // TODO: garbage collection ArrayList<FunctionSignature> imports = m.beamData().importTableChunk().imports(); FunctionSignature s = imports.get(bif.toInteger().toInt()); List args = List.nil; if (arg2 instanceof Integer) { args = new List(arg2, args); } else if (arg2.isXRegister()) { args = new List(arg2.toArg(process), args); } else { throw new Error("Unsupported ARG2: " + arg2); } if (arg1.isXRegister() || arg1.isYRegister()) { args = new List(arg1.toArg(process), args); } else if (arg1 instanceof Integer) { args = new List(arg1, args); } else { throw new Error("Unsupported ARG1: " + arg1); } Term result = Erlang.apply(s.module(), s.function(), args); // Store result in register Integer registerIndex = reg.toRegisterIndex(); if (reg.isXRegister()) { process.setX(registerIndex, result); } else if (reg.isYRegister()) { process.setY(registerIndex, result); } else { throw new Error("Unsupported destination: " + reg); } return null; } }