JSFiddle - React, Tailwind, and code Playground
HTML
<textarea id="txtBin">
01 00 00 00 01 01 00 01 02 01 00 01 01 00 00 02
01 02 00 03 04 01 00 02 01 02 00 04 01 03 00 05
03 00 02 03 01 02 00 06 02 01 01 02 01 02 00 07
04 01 02 00
</textarea>
<button id="btnRun">Run</button>
<script>
// TODO: 序列化成二进制数据
var CONST_DATA = [
window, 'document', 'createElement', 'script',
'text', 'alert(123)', 'body', 'appendChild'
];
</script>
CSS
textarea {
width: 500px;
height: 200px;
font-family: monospace;
}
JavaScript
var BASE = 1024;
var MEM = [];
var REG = [];
btnRun.onclick = function() {
// 加载常量数据
MEM = CONST_DATA.concat();
// 加载指令到存储
txtBin.value.split(/\s+/).forEach(function(hex, i) {
MEM[BASE + i] = parseInt(hex, 16);
});
pc = BASE;
run();
};
function readPC8() {
return MEM[pc++] | 0;
}
function readPC16() {
var v = (MEM[pc] << 8) | MEM[pc + 1];
pc += 2;
return v;
}
function run() {
var r1, r2, r3, r4;
var imm;
var obj, key, val;
for (;;) {
var opcode = readPC8();
if (!opcode) {
break;
}
switch (opcode) {
case 0x01: // LDR
r1 = readPC8();
imm = readPC16();
REG[r1] = MEM[imm];
break;
case 0x02: // GET
r1 = readPC8();
r2 = readPC8();
r3 = readPC8();
obj = REG[r2];
key = REG[r3];
REG[r1] = obj[key];
break;
case 0x03: // SET
r1 = readPC8();
r2 = readPC8();
r3 = readPC8();
obj = REG[r1];
key = REG[r2];
val = REG[r3];
obj[key] = val;
break;
case 0x04: // CAL
r1 = readPC8();
r2 = readPC8();
r3 = readPC8();
obj = REG[r1];
key = REG[r2];
REG[0] = obj[key]( REG[r3] );
break;
case 0x05: // JMP
imm = readPC16();
pc = pc + imm - 2;
break;
// ...
default: // Unknown
debugger;
}
}
}