mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 22:58:29 +08:00
Refactored opcode types to make them structurally clonable.
This commit is contained in:
parent
b928738d06
commit
fbef785410
@ -180,7 +180,9 @@ function params_to_code(params: any[]) {
|
||||
type = "TYPE_REG_REF";
|
||||
break;
|
||||
case "reg_tup_ref":
|
||||
type = `new RegTupRefType(${params_to_code(param.reg_tup)})`;
|
||||
type = `{ kind: Kind.RegTupRef, register_tuples: [${params_to_code(
|
||||
param.reg_tup
|
||||
)}] }`;
|
||||
break;
|
||||
case "reg_ref_var":
|
||||
type = "TYPE_REG_REF_VAR";
|
||||
|
@ -2,6 +2,7 @@ import Logger from "js-logger";
|
||||
import { Endianness } from "../..";
|
||||
import { ControlFlowGraph } from "../../../scripting/data_flow_analysis/ControlFlowGraph";
|
||||
import { register_value } from "../../../scripting/data_flow_analysis/register_value";
|
||||
import { stack_value } from "../../../scripting/data_flow_analysis/stack_value";
|
||||
import {
|
||||
Arg,
|
||||
DataSegment,
|
||||
@ -11,31 +12,12 @@ import {
|
||||
SegmentType,
|
||||
StringSegment,
|
||||
} from "../../../scripting/instructions";
|
||||
import {
|
||||
Opcode,
|
||||
OPCODES,
|
||||
RegTupRefType,
|
||||
StackInteraction,
|
||||
TYPE_BYTE,
|
||||
TYPE_DWORD,
|
||||
TYPE_D_LABEL,
|
||||
TYPE_FLOAT,
|
||||
TYPE_I_LABEL,
|
||||
TYPE_I_LABEL_VAR,
|
||||
TYPE_LABEL,
|
||||
TYPE_REF,
|
||||
TYPE_REG_REF,
|
||||
TYPE_REG_REF_VAR,
|
||||
TYPE_STRING,
|
||||
TYPE_S_LABEL,
|
||||
TYPE_WORD,
|
||||
} from "../../../scripting/opcodes";
|
||||
import { Kind, Opcode, OPCODES, StackInteraction } from "../../../scripting/opcodes";
|
||||
import { ArrayBufferCursor } from "../../cursor/ArrayBufferCursor";
|
||||
import { Cursor } from "../../cursor/Cursor";
|
||||
import { ResizableBufferCursor } from "../../cursor/ResizableBufferCursor";
|
||||
import { WritableCursor } from "../../cursor/WritableCursor";
|
||||
import { ResizableBuffer } from "../../ResizableBuffer";
|
||||
import { stack_value } from "../../../scripting/data_flow_analysis/stack_value";
|
||||
|
||||
const logger = Logger.get("data_formats/parsing/quest/bin");
|
||||
|
||||
@ -370,8 +352,8 @@ function find_and_parse_segments(
|
||||
for (let i = 0; i < instruction.opcode.params.length; i++) {
|
||||
const param = instruction.opcode.params[i];
|
||||
|
||||
switch (param.type) {
|
||||
case TYPE_I_LABEL:
|
||||
switch (param.type.kind) {
|
||||
case Kind.ILabel:
|
||||
get_arg_label_values(
|
||||
cfg,
|
||||
labels,
|
||||
@ -380,7 +362,7 @@ function find_and_parse_segments(
|
||||
SegmentType.Instructions
|
||||
);
|
||||
break;
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.ILabelVar:
|
||||
// Never on the stack.
|
||||
// Eat all remaining arguments.
|
||||
for (; i < instruction.args.length; i++) {
|
||||
@ -388,31 +370,29 @@ function find_and_parse_segments(
|
||||
}
|
||||
|
||||
break;
|
||||
case TYPE_D_LABEL:
|
||||
case Kind.DLabel:
|
||||
get_arg_label_values(cfg, labels, instruction, i, SegmentType.Data);
|
||||
break;
|
||||
case TYPE_S_LABEL:
|
||||
case Kind.SLabel:
|
||||
get_arg_label_values(cfg, labels, instruction, i, SegmentType.String);
|
||||
break;
|
||||
default:
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
// Never on the stack.
|
||||
const arg = instruction.args[i];
|
||||
case Kind.RegTupRef:
|
||||
// Never on the stack.
|
||||
const arg = instruction.args[i];
|
||||
|
||||
for (let j = 0; j < param.type.register_tuples.length; j++) {
|
||||
const reg_tup = param.type.register_tuples[j];
|
||||
for (let j = 0; j < param.type.register_tuples.length; j++) {
|
||||
const reg_tup = param.type.register_tuples[j];
|
||||
|
||||
if (reg_tup.type === TYPE_I_LABEL) {
|
||||
const label_values = register_value(
|
||||
cfg,
|
||||
instruction,
|
||||
arg.value + j
|
||||
);
|
||||
if (reg_tup.type.kind === Kind.ILabel) {
|
||||
const label_values = register_value(
|
||||
cfg,
|
||||
instruction,
|
||||
arg.value + j
|
||||
);
|
||||
|
||||
if (label_values.size() <= 10) {
|
||||
for (const label of label_values) {
|
||||
labels.set(label, SegmentType.Instructions);
|
||||
}
|
||||
if (label_values.size() <= 10) {
|
||||
for (const label of label_values) {
|
||||
labels.set(label, SegmentType.Instructions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -646,26 +626,26 @@ function parse_instruction_arguments(cursor: Cursor, opcode: Opcode): Arg[] {
|
||||
|
||||
if (opcode.stack !== StackInteraction.Pop) {
|
||||
for (const param of opcode.params) {
|
||||
switch (param.type) {
|
||||
case TYPE_BYTE:
|
||||
switch (param.type.kind) {
|
||||
case Kind.Byte:
|
||||
args.push({ value: cursor.u8(), size: 1 });
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
case Kind.Word:
|
||||
args.push({ value: cursor.u16(), size: 2 });
|
||||
break;
|
||||
case TYPE_DWORD:
|
||||
case Kind.DWord:
|
||||
args.push({ value: cursor.i32(), size: 4 });
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case Kind.Float:
|
||||
args.push({ value: cursor.f32(), size: 4 });
|
||||
break;
|
||||
case TYPE_LABEL:
|
||||
case TYPE_I_LABEL:
|
||||
case TYPE_D_LABEL:
|
||||
case TYPE_S_LABEL:
|
||||
case Kind.Label:
|
||||
case Kind.ILabel:
|
||||
case Kind.DLabel:
|
||||
case Kind.SLabel:
|
||||
args.push({ value: cursor.u16(), size: 2 });
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case Kind.String:
|
||||
{
|
||||
const start_pos = cursor.position;
|
||||
args.push({
|
||||
@ -678,28 +658,24 @@ function parse_instruction_arguments(cursor: Cursor, opcode: Opcode): Arg[] {
|
||||
});
|
||||
}
|
||||
break;
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.ILabelVar:
|
||||
{
|
||||
const arg_size = cursor.u8();
|
||||
args.push(...cursor.u16_array(arg_size).map(value => ({ value, size: 2 })));
|
||||
}
|
||||
break;
|
||||
case TYPE_REG_REF:
|
||||
case Kind.RegRef:
|
||||
case Kind.RegTupRef:
|
||||
args.push({ value: cursor.u8(), size: 1 });
|
||||
break;
|
||||
case TYPE_REG_REF_VAR:
|
||||
case Kind.RegRefVar:
|
||||
{
|
||||
const arg_size = cursor.u8();
|
||||
args.push(...cursor.u8_array(arg_size).map(value => ({ value, size: 1 })));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
args.push({ value: cursor.u8(), size: 1 });
|
||||
break;
|
||||
} else {
|
||||
throw new Error(`Parameter type ${param.type} not implemented.`);
|
||||
}
|
||||
throw new Error(`Parameter type ${Kind[param.type.kind]} not implemented.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -736,61 +712,57 @@ function write_object_code(
|
||||
const args = instruction.param_to_args[i];
|
||||
const [arg] = args;
|
||||
|
||||
switch (param.type) {
|
||||
case TYPE_BYTE:
|
||||
switch (param.type.kind) {
|
||||
case Kind.Byte:
|
||||
if (arg.value >= 0) {
|
||||
cursor.write_u8(arg.value);
|
||||
} else {
|
||||
cursor.write_i8(arg.value);
|
||||
}
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
case Kind.Word:
|
||||
if (arg.value >= 0) {
|
||||
cursor.write_u16(arg.value);
|
||||
} else {
|
||||
cursor.write_i16(arg.value);
|
||||
}
|
||||
break;
|
||||
case TYPE_DWORD:
|
||||
case Kind.DWord:
|
||||
if (arg.value >= 0) {
|
||||
cursor.write_u32(arg.value);
|
||||
} else {
|
||||
cursor.write_i32(arg.value);
|
||||
}
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case Kind.Float:
|
||||
cursor.write_f32(arg.value);
|
||||
break;
|
||||
case TYPE_LABEL: // Abstract type
|
||||
case TYPE_I_LABEL:
|
||||
case TYPE_D_LABEL:
|
||||
case TYPE_S_LABEL:
|
||||
case Kind.Label:
|
||||
case Kind.ILabel:
|
||||
case Kind.DLabel:
|
||||
case Kind.SLabel:
|
||||
cursor.write_u16(arg.value);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case Kind.String:
|
||||
cursor.write_string_utf16(arg.value, arg.size);
|
||||
break;
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.ILabelVar:
|
||||
cursor.write_u8(args.length);
|
||||
cursor.write_u16_array(args.map(arg => arg.value));
|
||||
break;
|
||||
case TYPE_REF: // Abstract type
|
||||
case TYPE_REG_REF:
|
||||
case Kind.RegRef:
|
||||
case Kind.RegTupRef:
|
||||
cursor.write_u8(arg.value);
|
||||
break;
|
||||
case TYPE_REG_REF_VAR:
|
||||
case Kind.RegRefVar:
|
||||
cursor.write_u8(args.length);
|
||||
cursor.write_u8_array(args.map(arg => arg.value));
|
||||
break;
|
||||
default:
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
cursor.write_u8(arg.value);
|
||||
} else {
|
||||
// TYPE_ANY and TYPE_POINTER cannot be serialized.
|
||||
throw new Error(
|
||||
`Parameter type ${param.type} not implemented.`
|
||||
);
|
||||
}
|
||||
// TYPE_ANY, TYPE_VALUE and TYPE_POINTER cannot be serialized.
|
||||
throw new Error(
|
||||
`Parameter type ${Kind[param.type.kind]} not implemented.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Logger from "js-logger";
|
||||
import { reinterpret_f32_as_i32 } from "../primitive_conversion";
|
||||
import {
|
||||
AssemblyLexer,
|
||||
CodeSectionToken,
|
||||
@ -7,40 +8,21 @@ import {
|
||||
IntToken,
|
||||
LabelToken,
|
||||
RegisterToken,
|
||||
Token,
|
||||
TokenType,
|
||||
StringSectionToken,
|
||||
StringToken,
|
||||
Token,
|
||||
TokenType,
|
||||
} from "./AssemblyLexer";
|
||||
import {
|
||||
Segment,
|
||||
Arg,
|
||||
InstructionSegment,
|
||||
SegmentType,
|
||||
Instruction,
|
||||
DataSegment,
|
||||
Instruction,
|
||||
InstructionSegment,
|
||||
Segment,
|
||||
SegmentType,
|
||||
StringSegment,
|
||||
} from "./instructions";
|
||||
import {
|
||||
Opcode,
|
||||
OPCODES_BY_MNEMONIC,
|
||||
Param,
|
||||
TYPE_I_LABEL_VAR,
|
||||
TYPE_REG_REF_VAR,
|
||||
StackInteraction,
|
||||
TYPE_BYTE,
|
||||
TYPE_DWORD,
|
||||
TYPE_WORD,
|
||||
TYPE_FLOAT,
|
||||
TYPE_S_LABEL,
|
||||
TYPE_D_LABEL,
|
||||
TYPE_I_LABEL,
|
||||
TYPE_LABEL,
|
||||
TYPE_STRING,
|
||||
TYPE_REG_REF,
|
||||
RegTupRefType,
|
||||
} from "./opcodes";
|
||||
import { reinterpret_f32_as_i32 } from "../primitive_conversion";
|
||||
import { Kind, Opcode, OPCODES_BY_MNEMONIC, Param, StackInteraction } from "./opcodes";
|
||||
|
||||
const logger = Logger.get("scripting/assembly");
|
||||
|
||||
@ -400,7 +382,7 @@ class Assembler {
|
||||
} else {
|
||||
const varargs =
|
||||
opcode.params.findIndex(
|
||||
p => p.type === TYPE_I_LABEL_VAR || p.type === TYPE_REG_REF_VAR
|
||||
p => p.type.kind === Kind.ILabelVar || p.type.kind === Kind.RegRefVar
|
||||
) !== -1;
|
||||
|
||||
const param_count =
|
||||
@ -464,28 +446,29 @@ class Assembler {
|
||||
const [arg, token] = arg_and_token;
|
||||
|
||||
if (token.type === TokenType.Register) {
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
if (param.type.kind === Kind.RegTupRef) {
|
||||
this.add_instruction(Opcode.ARG_PUSHB, [arg]);
|
||||
} else {
|
||||
this.add_instruction(Opcode.ARG_PUSHR, [arg]);
|
||||
}
|
||||
} else {
|
||||
switch (param.type) {
|
||||
case TYPE_BYTE:
|
||||
case TYPE_REG_REF:
|
||||
switch (param.type.kind) {
|
||||
case Kind.Byte:
|
||||
case Kind.RegRef:
|
||||
case Kind.RegTupRef:
|
||||
this.add_instruction(Opcode.ARG_PUSHB, [arg]);
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
case TYPE_LABEL:
|
||||
case TYPE_I_LABEL:
|
||||
case TYPE_D_LABEL:
|
||||
case TYPE_S_LABEL:
|
||||
case Kind.Word:
|
||||
case Kind.Label:
|
||||
case Kind.ILabel:
|
||||
case Kind.DLabel:
|
||||
case Kind.SLabel:
|
||||
this.add_instruction(Opcode.ARG_PUSHW, [arg]);
|
||||
break;
|
||||
case TYPE_DWORD:
|
||||
case Kind.DWord:
|
||||
this.add_instruction(Opcode.ARG_PUSHL, [arg]);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case Kind.Float:
|
||||
this.add_instruction(Opcode.ARG_PUSHL, [
|
||||
{
|
||||
value: reinterpret_f32_as_i32(arg.value),
|
||||
@ -493,18 +476,15 @@ class Assembler {
|
||||
},
|
||||
]);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case Kind.String:
|
||||
this.add_instruction(Opcode.ARG_PUSHS, [arg]);
|
||||
break;
|
||||
default:
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
this.add_instruction(Opcode.ARG_PUSHB, [arg]);
|
||||
} else {
|
||||
logger.error(
|
||||
`Line ${this.line_no}: Type ${param.type} not implemented.`
|
||||
);
|
||||
}
|
||||
|
||||
logger.error(
|
||||
`Line ${this.line_no}: Type ${
|
||||
Kind[param.type.kind]
|
||||
} not implemented.`
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -535,7 +515,7 @@ class Assembler {
|
||||
message: "Expected an argument.",
|
||||
});
|
||||
} else {
|
||||
if (param.type !== TYPE_I_LABEL_VAR && param.type !== TYPE_REG_REF_VAR) {
|
||||
if (param.type.kind !== Kind.ILabelVar && param.type.kind !== Kind.RegRefVar) {
|
||||
param_i++;
|
||||
}
|
||||
}
|
||||
@ -559,25 +539,25 @@ class Assembler {
|
||||
|
||||
switch (token.type) {
|
||||
case TokenType.Int:
|
||||
switch (param.type) {
|
||||
case TYPE_BYTE:
|
||||
switch (param.type.kind) {
|
||||
case Kind.Byte:
|
||||
match = true;
|
||||
this.parse_int(1, token, arg_and_tokens);
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
case TYPE_LABEL:
|
||||
case TYPE_I_LABEL:
|
||||
case TYPE_D_LABEL:
|
||||
case TYPE_S_LABEL:
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.Word:
|
||||
case Kind.Label:
|
||||
case Kind.ILabel:
|
||||
case Kind.DLabel:
|
||||
case Kind.SLabel:
|
||||
case Kind.ILabelVar:
|
||||
match = true;
|
||||
this.parse_int(2, token, arg_and_tokens);
|
||||
break;
|
||||
case TYPE_DWORD:
|
||||
case Kind.DWord:
|
||||
match = true;
|
||||
this.parse_int(4, token, arg_and_tokens);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case Kind.Float:
|
||||
match = true;
|
||||
arg_and_tokens.push([
|
||||
{
|
||||
@ -593,7 +573,7 @@ class Assembler {
|
||||
}
|
||||
break;
|
||||
case TokenType.Float:
|
||||
match = param.type === TYPE_FLOAT;
|
||||
match = param.type.kind === Kind.Float;
|
||||
|
||||
if (match) {
|
||||
arg_and_tokens.push([
|
||||
@ -609,14 +589,14 @@ class Assembler {
|
||||
case TokenType.Register:
|
||||
match =
|
||||
stack ||
|
||||
param.type === TYPE_REG_REF ||
|
||||
param.type === TYPE_REG_REF_VAR ||
|
||||
param.type instanceof RegTupRefType;
|
||||
param.type.kind === Kind.RegRef ||
|
||||
param.type.kind === Kind.RegRefVar ||
|
||||
param.type.kind === Kind.RegTupRef;
|
||||
|
||||
this.parse_register(token, arg_and_tokens);
|
||||
break;
|
||||
case TokenType.String:
|
||||
match = param.type === TYPE_STRING;
|
||||
match = param.type.kind === Kind.String;
|
||||
|
||||
if (match) {
|
||||
arg_and_tokens.push([
|
||||
@ -639,44 +619,40 @@ class Assembler {
|
||||
|
||||
let type_str: string | undefined;
|
||||
|
||||
switch (param.type) {
|
||||
case TYPE_BYTE:
|
||||
switch (param.type.kind) {
|
||||
case Kind.Byte:
|
||||
type_str = "a 8-bit integer";
|
||||
break;
|
||||
case TYPE_WORD:
|
||||
case Kind.Word:
|
||||
type_str = "a 16-bit integer";
|
||||
break;
|
||||
case TYPE_DWORD:
|
||||
case Kind.DWord:
|
||||
type_str = "a 32-bit integer";
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case Kind.Float:
|
||||
type_str = "a float";
|
||||
break;
|
||||
case TYPE_LABEL:
|
||||
case Kind.Label:
|
||||
type_str = "a label";
|
||||
break;
|
||||
case TYPE_I_LABEL:
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.ILabel:
|
||||
case Kind.ILabelVar:
|
||||
type_str = "an instruction label";
|
||||
break;
|
||||
case TYPE_D_LABEL:
|
||||
case Kind.DLabel:
|
||||
type_str = "a data label";
|
||||
break;
|
||||
case TYPE_S_LABEL:
|
||||
case Kind.SLabel:
|
||||
type_str = "a string label";
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case Kind.String:
|
||||
type_str = "a string";
|
||||
break;
|
||||
case TYPE_REG_REF:
|
||||
case TYPE_REG_REF_VAR:
|
||||
case Kind.RegRef:
|
||||
case Kind.RegRefVar:
|
||||
case Kind.RegTupRef:
|
||||
type_str = "a register reference";
|
||||
break;
|
||||
default:
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
type_str = "a register reference";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (type_str) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import Logger from "js-logger";
|
||||
import { Instruction } from "../instructions";
|
||||
import {
|
||||
Kind,
|
||||
MAX_SIGNED_DWORD_VALUE,
|
||||
MIN_SIGNED_DWORD_VALUE,
|
||||
Opcode,
|
||||
ParamAccess,
|
||||
RegTupRefType,
|
||||
} from "../opcodes";
|
||||
import { BasicBlock, ControlFlowGraph } from "./ControlFlowGraph";
|
||||
import { ValueSet } from "./ValueSet";
|
||||
@ -167,7 +167,7 @@ function find_values(
|
||||
for (let j = 0; j < arg_len; j++) {
|
||||
const param = params[j];
|
||||
|
||||
if (param.type instanceof RegTupRefType) {
|
||||
if (param.type.kind == Kind.RegTupRef) {
|
||||
const reg_ref = args[j].value;
|
||||
let k = 0;
|
||||
|
||||
|
@ -1,15 +1,6 @@
|
||||
import { Arg, Segment, SegmentType } from "./instructions";
|
||||
import {
|
||||
Param,
|
||||
StackInteraction,
|
||||
TYPE_STRING,
|
||||
TYPE_I_LABEL_VAR,
|
||||
TYPE_REG_REF_VAR,
|
||||
TYPE_REG_REF,
|
||||
RegTupRefType,
|
||||
TYPE_FLOAT,
|
||||
} from "./opcodes";
|
||||
import { reinterpret_i32_as_f32 } from "../primitive_conversion";
|
||||
import { Arg, Segment, SegmentType } from "./instructions";
|
||||
import { Kind, Param, StackInteraction } from "./opcodes";
|
||||
|
||||
/**
|
||||
* @param manual_stack If true, will output stack management instructions (argpush variants). Otherwise the arguments of stack management instructions will be output as arguments to the instruction that pops them from the stack.
|
||||
@ -123,8 +114,8 @@ function args_to_strings(params: Param[], args: Arg[], stack: boolean): string[]
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TYPE_FLOAT:
|
||||
switch (type.kind) {
|
||||
case Kind.Float:
|
||||
// Floats are pushed onto the stack as integers with arg_pushl.
|
||||
if (stack) {
|
||||
arg_strings.push(reinterpret_i32_as_f32(arg.value).toString());
|
||||
@ -132,28 +123,25 @@ function args_to_strings(params: Param[], args: Arg[], stack: boolean): string[]
|
||||
arg_strings.push(arg.value.toString());
|
||||
}
|
||||
break;
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case Kind.ILabelVar:
|
||||
for (; i < args.length; i++) {
|
||||
arg_strings.push(args[i].value.toString());
|
||||
}
|
||||
break;
|
||||
case TYPE_REG_REF_VAR:
|
||||
case Kind.RegRefVar:
|
||||
for (; i < args.length; i++) {
|
||||
arg_strings.push("r" + args[i].value);
|
||||
}
|
||||
break;
|
||||
case TYPE_REG_REF:
|
||||
case Kind.RegRef:
|
||||
case Kind.RegTupRef:
|
||||
arg_strings.push("r" + arg.value);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case Kind.String:
|
||||
arg_strings.push(JSON.stringify(arg.value));
|
||||
break;
|
||||
default:
|
||||
if (type instanceof RegTupRefType) {
|
||||
arg_strings.push("r" + arg.value);
|
||||
} else {
|
||||
arg_strings.push(arg.value.toString());
|
||||
}
|
||||
arg_strings.push(arg.value.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { TYPE_I_LABEL_VAR, TYPE_REG_REF_VAR, Opcode } from "./opcodes";
|
||||
import { Kind, Opcode } from "./opcodes";
|
||||
|
||||
/**
|
||||
* Instruction invocation.
|
||||
@ -25,9 +25,9 @@ export class Instruction {
|
||||
const arg = args[i];
|
||||
this.param_to_args[i] = [];
|
||||
|
||||
switch (type) {
|
||||
case TYPE_I_LABEL_VAR:
|
||||
case TYPE_REG_REF_VAR:
|
||||
switch (type.kind) {
|
||||
case Kind.ILabelVar:
|
||||
case Kind.RegRefVar:
|
||||
this.arg_size++;
|
||||
|
||||
for (let j = i; j < args.length; j++) {
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user