Revert "libifps: allow reading invalid operands"

This reverts commit 58e78597e7.
This commit is contained in:
zc 2023-03-31 12:36:20 +01:00
parent 58e78597e7
commit 6feeac38f7
5 changed files with 27 additions and 78 deletions

View File

@ -24,10 +24,6 @@ namespace IFPSLib.Emit
/// <summary> /// <summary>
/// Operand refers to an element of an indexed variable, where the index is specified as a local or global variable, or an argument. /// Operand refers to an element of an indexed variable, where the index is specified as a local or global variable, or an argument.
/// </summary> /// </summary>
IndexedVariable, IndexedVariable
/// <summary>
/// Operand is invalid. Stops execution.
/// </summary>
Invalid = 0xff
} }
} }

View File

@ -5,8 +5,6 @@ using System.IO;
using System.Text; using System.Text;
using System.Linq; using System.Linq;
using System.Collections; using System.Collections;
using System.Net;
using System.Data;
namespace IFPSLib.Emit namespace IFPSLib.Emit
{ {
@ -382,31 +380,6 @@ namespace IFPSLib.Emit
return FixBranchOffset(br, br.Read<uint>()); return FixBranchOffset(br, br.Read<uint>());
} }
private static T TryReadIndex<T>(BinaryReader br, IList<T> list)
{
var index = (int)br.Read<uint>();
if (index < list.Count) return list[index];
return default;
}
private static Operand TryReadFunction(BinaryReader br, Script script)
{
var func = TryReadIndex(br, script.Functions);
if (func == null) func = new ScriptFunction()
{
Name = "INVALID",
Arguments = new List<FunctionArgument>()
};
return Operand.Create(func);
}
private static Operand TryReadType(BinaryReader br, Script script)
{
var type = TryReadIndex(br, script.Types);
if (type == null) type = UnknownType.Instance;
return Operand.Create(type);
}
internal static Instruction Load(BinaryReader br, Script script, ScriptFunction function) internal static Instruction Load(BinaryReader br, Script script, ScriptFunction function)
{ {
var ret = new Instruction(); var ret = new Instruction();
@ -464,10 +437,10 @@ namespace IFPSLib.Emit
ret.m_Operands = new List<Operand>(2) { new Operand(new TypedData(InstructionType.Instance, FixBranchOffset(br, brOffset))), valOp }; ret.m_Operands = new List<Operand>(2) { new Operand(new TypedData(InstructionType.Instance, FixBranchOffset(br, brOffset))), valOp };
break; break;
case OperandType.InlineFunction: case OperandType.InlineFunction:
ret.m_Operands = new List<Operand>(1) { TryReadFunction(br, script) }; ret.m_Operands = new List<Operand>(1) { Operand.Create(script.Functions[(int)br.Read<uint>()]) };
break; break;
case OperandType.InlineType: case OperandType.InlineType:
ret.m_Operands = new List<Operand>(1) { TryReadType(br, script) }; ret.m_Operands = new List<Operand>(1) { Operand.Create(script.Types[(int)br.Read<uint>()]) };
break; break;
case OperandType.InlineCmpValue: case OperandType.InlineCmpValue:
ret.m_Operands = new List<Operand>(3) { Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function) }; ret.m_Operands = new List<Operand>(3) { Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function) };
@ -476,7 +449,7 @@ namespace IFPSLib.Emit
ret.m_Operands = new List<Operand>(3) { ret.m_Operands = new List<Operand>(3) {
Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function),
Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function),
TryReadType(br, script) Operand.Create(script.Types[(int)br.Read<uint>()])
}; };
break; break;
case OperandType.InlineEH: case OperandType.InlineEH:
@ -493,7 +466,7 @@ namespace IFPSLib.Emit
break; break;
case OperandType.InlineTypeVariable: case OperandType.InlineTypeVariable:
ret.m_Operands = new List<Operand>(2) { ret.m_Operands = new List<Operand>(2) {
TryReadType(br, script), Operand.Create(script.Types[(int)br.Read<uint>()]),
new Operand(VariableBase.Load(br, script, function)) new Operand(VariableBase.Load(br, script, function))
}; };
return ret; return ret;

View File

@ -105,12 +105,6 @@ namespace IFPSLib.Emit
m_Value = op.m_Value; m_Value = op.m_Value;
} }
private Operand(Exception ex = null)
{
m_Type = BytecodeOperandType.Invalid;
if (ex != null) m_Value.Immediate = new TypedData(Types.UnknownType.Instance, ex);
}
public static Operand Create<TType>(Types.PrimitiveType type, TType value) public static Operand Create<TType>(Types.PrimitiveType type, TType value)
{ {
return new Operand(TypedData.Create(type, value)); return new Operand(TypedData.Create(type, value));
@ -162,39 +156,31 @@ namespace IFPSLib.Emit
return new Operand(arr, varIdx); return new Operand(arr, varIdx);
} }
public static Operand CreateInvalid(Exception ex = null)
{
return new Operand(ex);
}
internal static Operand LoadValue(BinaryReader br, Script script, ScriptFunction function) internal static Operand LoadValue(BinaryReader br, Script script, ScriptFunction function)
{ {
var type = (BytecodeOperandType)br.ReadByte(); var type = (BytecodeOperandType)br.ReadByte();
try switch (type)
{ {
switch (type) case BytecodeOperandType.Variable:
{ return new Operand(VariableBase.Load(br, script, function));
case BytecodeOperandType.Variable: case BytecodeOperandType.Immediate:
return new Operand(VariableBase.Load(br, script, function)); return new Operand(TypedData.Load(br, script));
case BytecodeOperandType.Immediate: case BytecodeOperandType.IndexedImmediate:
return new Operand(TypedData.Load(br, script)); {
case BytecodeOperandType.IndexedImmediate: var variable = VariableBase.Load(br, script, function);
{ var idx = br.Read<uint>();
var variable = VariableBase.Load(br, script, function); return Create(variable, idx);
var idx = br.Read<uint>(); }
return Create(variable, idx); case BytecodeOperandType.IndexedVariable:
} {
case BytecodeOperandType.IndexedVariable: var variable = VariableBase.Load(br, script, function);
{ var idx = VariableBase.Load(br, script, function);
var variable = VariableBase.Load(br, script, function); return new Operand(variable, idx);
var idx = VariableBase.Load(br, script, function); }
return new Operand(variable, idx); default:
} throw new ArgumentOutOfRangeException(string.Format("Invalid operand type {0}", (byte)type));
default: }
throw new ArgumentOutOfRangeException(string.Format("Invalid operand type {0}", (byte)type));
}
} catch (Exception ex) { return new Operand(ex); }
} }
public override string ToString() public override string ToString()
@ -209,8 +195,6 @@ namespace IFPSLib.Emit
return String.Format("{0}[{1}]", IndexedVariable.Name, IndexImmediate); return String.Format("{0}[{1}]", IndexedVariable.Name, IndexImmediate);
case BytecodeOperandType.IndexedVariable: case BytecodeOperandType.IndexedVariable:
return String.Format("{0}[{1}]", IndexedVariable.Name, IndexVariable.Name); return String.Format("{0}[{1}]", IndexedVariable.Name, IndexVariable.Name);
case BytecodeOperandType.Invalid:
return "$INVALID";
default: default:
return ""; return "";
} }

View File

@ -313,11 +313,7 @@ namespace IFPSLib
switch (Type.BaseType) switch (Type.BaseType)
{ {
case PascalTypeCode.Type: case PascalTypeCode.Type:
{ return ValueAs<IType>().Name;
var type = ValueAs<IType>();
if (type is UnknownType) return "$UNKNOWN";
return type.Name;
}
case PascalTypeCode.Instruction: case PascalTypeCode.Instruction:
if (Value == null) return "null"; if (Value == null) return "null";
return string.Format("loc_{0}", ValueAs<Emit.Instruction>().Offset.ToString("x")); return string.Format("loc_{0}", ValueAs<Emit.Instruction>().Offset.ToString("x"));

View File

@ -19,7 +19,7 @@ Library implementing an assembler for IFPS scripts.
Depends on IFPSLib. Depends on IFPSLib.
Assembling the output of IFPSLib's disassembler (for sane bytecode with no invalid instructions/operands) is expected to output an identical binary, not doing so is considered a bug. Assembling the output of IFPSLib's disassembler is expected to output an identical binary, not doing so is considered a bug.
## ifpsdasm ## ifpsdasm