/*
* Copyright 2014 JBoss Inc
*
* 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 org.dynjs.ir;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.dynjs.ir.instructions.ResultInstruction;
import org.dynjs.ir.operands.Variable;
public abstract class Instruction {
private final Operation operation;
// Mutable state to make it easier for jumping around
private int ipc = -1;
public Instruction(Operation operation) {
this.operation = operation;
}
public int getIPC() {
return ipc;
}
public void setIPC(int ipc) {
this.ipc = ipc;
}
/**
* List of all variables used by this instruction.
*/
public List<Variable> getUsedVariables() {
ArrayList<Variable> vars = new ArrayList<Variable>();
for (Operand o : getOperands()) {
o.addUsedVariables(vars);
}
return vars;
}
public void simplifyOperands(Map<Operand, Operand> renameMap, boolean force) {
}
public void renameVariables(Map<Operand, Operand> renameMap) {
simplifyOperands(renameMap, true);
if (this instanceof ResultInstruction) {
ResultInstruction resultInstruction = (ResultInstruction) this;
Variable oldVariable = resultInstruction.getResult();
Variable newVariable = (Variable) renameMap.get(oldVariable);
if (newVariable != null) resultInstruction.updateResult(newVariable);
}
}
public abstract Operand[] getOperands();
/**
* This instruction can set or hint or some useful information onto the scope it belongs
* to.
*
* @param scope is where this instruciton lives
* @return true if scope had information added otherwise return false
*/
public boolean computeScopeFlags(Scope scope) {
return false;
}
// jump/branch/return/exception (e.g. can jump out of current instr list)
public boolean transfersControl() {
return false;
}
/**
* Can this instruction potentially raise a JS Exception?
*/
public boolean canRaiseException() {
return false;
}
/**
* Dump out this instruction in a string frield format for debugging purposes.
*/
public String dump(String indent) {
return indent + getClass().getSimpleName();
}
public Operation getOperation() {
return operation;
}
}