Make _state_skip work by value (instead of key). Fixes certain Closure Compiler builds

This commit is contained in:
copy 2015-01-12 18:05:10 +01:00
parent 2940ef12c4
commit a0da169168
16 changed files with 215 additions and 175 deletions

View file

@ -301,14 +301,8 @@ var v86util = v86util || {};
{
this.onload && this.onload({});
};
this._state_skip = [
"file",
"block_count",
"byteLength",
"block_size",
];
}
AsyncFileBuffer.prototype.get = function(offset, len, fn)
{
console.assert(offset % this.block_size === 0);

View file

@ -12,25 +12,28 @@ function CPU()
this.segment_limits = [];
//this.segment_infos = [];
/*
/**
* Translation Lookaside Buffer
* @const
*/
this.tlb_data = [];
this.tlb_data = new Int32Array(1 << 20);
/*
/**
* Information about which pages are cached in the tlb.
* By bit:
* 0 system, read
* 1 system, write
* 2 user, read
* 3 user, write
* @const
*/
this.tlb_info = [];
this.tlb_info = new Uint8Array(1 << 20);
/*
/**
* Same as tlb_info, except it only contains global pages
* @const
*/
this.tlb_info_global = [];
this.tlb_info_global = new Uint8Array(1 << 20);
/**
* Wheter or not in protected mode
@ -180,8 +183,14 @@ function CPU()
/** @type {number} */
this.previous_ip = 0;
/** @type {!Object} */
this.bios = {};
/**
* @const
* @type {{main: ArrayBuffer, vga: ArrayBuffer}}
*/
this.bios = {
main: null,
vga: null,
};
/**
* @type {number}
@ -229,23 +238,10 @@ function CPU()
// Closure Compiler is able to remove unused functions
#include "debug.macro.js"
/** @const */
this._state_skip = [
"bios",
"debug",
"regv",
"table", "table0F",
"table16", "table32",
"table0F_16", "table0F_32",
"reg8", "reg8s",
"reg16", "reg16s", "reg32",
dbg_assert(this.table16 && this.table32);
dbg_assert(this.table0F_16 && this.table0F_32);
"tlb_data",
"tlb_info",
"tlb_info_global",
"timestamp_counter",
];
this._state_restore();
}
CPU.prototype._state_restore = function()
@ -271,6 +267,21 @@ CPU.prototype._state_restore = function()
this.full_clear_tlb();
this.timestamp_counter = 0;
this.tsc_offset = v86.microtick();
/** @const */
this._state_skip = [
this.bios,
this.debug,
this.table16,
this.table32,
this.table0F_16,
this.table0F_32,
this.tlb_data,
this.tlb_info,
this.tlb_info_global,
];
};
#include "translate.macro.js"
@ -348,11 +359,7 @@ CPU.prototype.reset = function()
//this.segment_infos = new Uint32Array(8);
this.segment_offsets = new Int32Array(8);
// 16 MB in total
this.tlb_data = new Int32Array(1 << 20);
this.tlb_info = new Uint8Array(1 << 20);
this.tlb_info_global = new Uint8Array(1 << 20);
this.full_clear_tlb();
this.reg32s = new Int32Array(8);
this.reg32 = new Uint32Array(this.reg32s.buffer);
@ -437,10 +444,8 @@ CPU.prototype.init = function(settings, device_bus)
var io = new IO(this.memory);
this.io = io;
this.bios = {
main: settings.bios,
vga: settings.vga_bios,
};
this.bios.main = settings.bios;
this.bios.vga = settings.vga_bios;
this.load_bios();

View file

@ -5,7 +5,7 @@
*/
function DMA(dev)
{
this.io = dev.io;
/** @const */
this.memory = dev.memory;
this.channels = [
@ -17,15 +17,18 @@ function DMA(dev)
this.lsb_msb_flipflop = 0;
this.io.register_write(0x04, this, this.port_write.bind(this, 0x04));
this.io.register_write(0x05, this, this.port_write.bind(this, 0x05));
this.io.register_write(0x0A, this, this.portA_write);
this.io.register_write(0x0B, this, this.portB_write);
this.io.register_write(0x0C, this, this.portC_write);
this.io.register_write(0x81, this, this.port81_write);
var io = dev.io;
io.register_write(0x04, this, this.port_write.bind(this, 0x04));
io.register_write(0x05, this, this.port_write.bind(this, 0x05));
io.register_write(0x0A, this, this.portA_write);
io.register_write(0x0B, this, this.portB_write);
io.register_write(0x0C, this, this.portC_write);
io.register_write(0x81, this, this.port81_write);
/** @const */
this._state_skip = ["io", "memory"];
this._state_skip = [
this.memory,
];
};
DMA.prototype.port_write = function(port, data_byte)

View file

@ -3,8 +3,13 @@
/** @constructor */
function FloppyController(cpu, fda_image, fdb_image)
{
/** @const */
this.io = cpu.io;
/** @const */
this.pic = cpu.devices.pic;
/** @const */
this.dma = cpu.devices.dma;
this.bytes_expecting = 0;
@ -18,9 +23,13 @@ function FloppyController(cpu, fda_image, fdb_image)
this.floppy_size = 0;
/** @const */
this.fda_image = fda_image;
/** @const */
this.fdb_image = fdb_image;
this.status_reg0 = 0;
this.status_reg1 = 0;
this.status_reg2 = 0;
@ -30,8 +39,17 @@ function FloppyController(cpu, fda_image, fdb_image)
this.last_head = 0;
this.last_sector = 1;
/** @const */
this._state_skip = [
this.io,
this.pic,
this.dma,
];
this._state_skip = ["io", "pic", "dma", "fda_image", "fdb_image"];
if(this.fdb_image)
{
this._state_skip.push(this.fdb_image);
}
if(!fda_image)
{
@ -39,6 +57,8 @@ function FloppyController(cpu, fda_image, fdb_image)
return;
}
this._state_skip.push(this.fda_image);
this.floppy_size = fda_image.byteLength;
var floppy_types = {

View file

@ -63,8 +63,8 @@ function FPU(cpu)
// Why no Float80Array :-(
this._st = new Float64Array(8);
this._st8 = new Uint8Array(this._st.buffer);
this._st32 = new Int32Array(this._st.buffer);
this._state_restore();
// bitmap of which stack registers are empty
this._stack_empty = 0xff;
@ -78,16 +78,6 @@ function FPU(cpu)
this._fpu_dp = 0;
this._fpu_dp_selector = 0;
/*
* used for conversion
*/
this.float32 = new Float32Array(1);
this.float32_byte = new Uint8Array(this.float32.buffer);
this.float32_int = new Int32Array(this.float32.buffer);
this.float64 = new Float64Array(1);
this.float64_byte = new Uint8Array(this.float64.buffer);
this.float64_int = new Int32Array(this.float64.buffer);
/** @const */
this.indefinite_nan = NaN;
@ -97,32 +87,35 @@ function FPU(cpu)
Math.log(2) / Math.LN10, Math.LN2, 0
]);
/** @const */
this._state_skip = [
"cpu",
"float32",
"float32_byte",
"float32_int",
"float64",
"float64_byte",
"float64_int",
"_st8",
"_st32",
];
}
FPU.prototype._state_restore = function()
{
this.float32 = new Float32Array(1);
this.float32_byte = new Uint8Array(this.float32.buffer);
this.float32_int = new Int32Array(this.float32.buffer);
// used for conversion
/** @const */ this.float32 = new Float32Array(1);
/** @const */ this.float32_byte = new Uint8Array(this.float32.buffer);
/** @const */ this.float32_int = new Int32Array(this.float32.buffer);
/** @const */ this.float64 = new Float64Array(1);
/** @const */ this.float64_byte = new Uint8Array(this.float64.buffer);
/** @const */ this.float64_int = new Int32Array(this.float64.buffer);
this.float64 = new Float64Array(1);
this.float64_byte = new Uint8Array(this.float64.buffer);
this.float64_int = new Int32Array(this.float64.buffer);
/** @const */ this._st8 = new Uint8Array(this._st.buffer);
/** @const */ this._st32 = new Int32Array(this._st.buffer);
this._st8 = new Uint8Array(this._st.buffer);
this._st32 = new Int32Array(this._st.buffer);
/** @const */
this._state_skip = [
this.cpu,
this.float32,
this.float32_byte,
this.float32_int,
this.float64,
this.float64_byte,
this.float64_int,
this._st8,
this._st32,
];
};
FPU.prototype._fpu_unimpl = function()

View file

@ -41,7 +41,10 @@ function IDEDevice(cpu, buffer, is_cd, nr)
/** @type {number} */
this.master_port = 0xC000;
/** @const */
this.pic = cpu.devices.pic;
/** @const */
this.memory = cpu.memory;
this.buffer = buffer;
@ -94,6 +97,7 @@ function IDEDevice(cpu, buffer, is_cd, nr)
}
}
/** @const */
this.stats = {
sectors_read: 0,
sectors_written: 0,
@ -275,9 +279,10 @@ function IDEDevice(cpu, buffer, is_cd, nr)
/** @const */
this._state_skip = [
"memory",
"pic",
"stats",
this.memory,
this.pic,
this.stats,
this.buffer,
];
}

View file

@ -10,8 +10,6 @@ function IO(memory)
{
var memory_size = memory.size;
this._state_skip = ["devices", "ports",];
function get_port_description(addr)
{
// via seabios ioport.h
@ -100,9 +98,18 @@ function IO(memory)
{
}
/** @const */
this.ports = [];
/** @const */
this.devices = Array(0x10000);
this._state_skip = [
this.ports,
this.devices,
];
for(var i = 0; i < 0x10000; i++)
{
this.ports[i] = {

View file

@ -5,14 +5,6 @@
*/
function Memory(memory_size)
{
var buffer = new ArrayBuffer(memory_size);
this.mem8 = new Uint8Array(buffer);
this.mem16 = new Uint16Array(buffer);
this.mem32s = new Int32Array(buffer);
this.buffer = buffer;
this.size = memory_size;
// this only supports a 32 bit address space
@ -20,38 +12,44 @@ function Memory(memory_size)
var memory_map_registered = new Uint8Array(size);
// managed by IO() in io.js
this.memory_map_registered = memory_map_registered;
this.memory_map_read8 = [];
this.memory_map_write8 = [];
this.memory_map_read32 = [];
this.memory_map_write32 = [];
/** @const */ this.memory_map_registered = memory_map_registered;
/** @const */ this.memory_map_read8 = [];
/** @const */ this.memory_map_write8 = [];
/** @const */ this.memory_map_read32 = [];
/** @const */ this.memory_map_write32 = [];
// use by dynamic translator
if(OP_TRANSLATION) this.mem_page_infos = new Uint8Array(1 << 20);
dbg_assert((memory_size & MMAP_BLOCK_SIZE - 1) === 0);
/** @const */
this._state_skip = [
"mem8",
"mem16",
"mem32s",
"memory_map_registered",
"memory_map_read8",
"memory_map_read32",
"memory_map_write8",
"memory_map_write32",
];
this.buffer = new ArrayBuffer(memory_size);;
this._state_restore();
};
Memory.prototype._state_restore = function()
{
//this.mem8 = new Uint8Array(this.mem32s.buffer, this.mem32s.byteOffset, this.mem32s.byteLength);
//this.mem16 = new Uint16Array(this.mem32s.buffer, this.mem32s.byteOffset, this.mem32s.byteLength >> 1);
/** @const */
this.mem8 = new Uint8Array(this.buffer);
/** @const */
this.mem16 = new Uint16Array(this.buffer);
/** @const */
this.mem32s = new Int32Array(this.buffer);
/** @const */
this._state_skip = [
this.mem8,
this.mem16,
this.mem32s,
this.memory_map_registered,
this.memory_map_read8,
this.memory_map_read32,
this.memory_map_write8,
this.memory_map_write32,
];
};
// called by all memory reads and writes

View file

@ -55,8 +55,10 @@
/** @constructor */
function Ne2k(cpu, bus)
{
/** @const */
this.pic = cpu.devices.pic;
/** @const */
this.bus = bus;
this.bus.register("net0-receive", function(data)
{
@ -362,8 +364,8 @@ function Ne2k(cpu, bus)
io.register_write(this.port | NE_DATAPORT | 0, this, this.data_port_write, this.data_port_write16, this.data_port_write32);
this._state_skip = [
"bus",
"pic",
this.bus,
this.pic,
];
}

View file

@ -14,6 +14,7 @@ var OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz
*/
function PIT(cpu)
{
/** @const */
this.pic = cpu.devices.pic;
this.next_tick = Date.now();
@ -54,7 +55,9 @@ function PIT(cpu)
cpu.io.register_write(0x43, this, this.port43_write);
/** @const */
this._state_skip = ["pic"];
this._state_skip = [
this.pic,
];
}
PIT.prototype.get_timer2 = function()

View file

@ -5,9 +5,12 @@
*/
function PS2(cpu, bus)
{
/** @const */
this.pic = cpu.devices.pic;
/** @const */
this.cpu = cpu;
/** @const */
this.bus = bus;
/** @type {boolean} */
@ -107,9 +110,9 @@ function PS2(cpu, bus)
/** @const */
this._state_skip = [
"bus",
"pic",
"cpu",
this.bus,
this.pic,
this.cpu,
];
}

View file

@ -4,7 +4,10 @@
*/
function RTC(cpu, diskette_type, boot_order)
{
/** @const */
this.cpu = cpu;
/** @const */
this.pic = cpu.devices.pic;
this.cmos_index = 0;
@ -40,7 +43,10 @@ function RTC(cpu, diskette_type, boot_order)
cpu.io.register_write(0x71, this, this.cmos_write);
cpu.io.register_read(0x71, this, this.cmos_read);
this._state_skip = ["cpu", "pic"];
this._state_skip = [
this.cpu,
this.pic,
];
}
RTC.prototype.timer = function(time, legacy_mode)

View file

@ -71,21 +71,21 @@ function save_object(obj, arraybuffers)
};
}
var skip = Array.setify(obj._state_skip || []);
skip["_state_skip"] = true;
var skip;
if(obj._state_skip)
{
skip = obj._state_skip.slice();
skip.push(obj._state_skip);
}
var keys = Object.keys(obj);
var result = {};
outer:
for(var i = 0; i < keys.length; i++)
{
var key = keys[i];
if(skip[key])
{
continue;
}
var value = obj[key];
if(typeof value === "function")
@ -93,6 +93,17 @@ function save_object(obj, arraybuffers)
continue;
}
if(skip && typeof value === "object" && value)
{
for(var j = 0; j < skip.length; j++)
{
if(skip[j] === value)
{
continue outer;
}
}
}
result[key] = save_object(value, arraybuffers);
}

View file

@ -26,8 +26,10 @@ var DLAB = 0x80;
*/
function UART(cpu, port, bus)
{
/** @const */
this.bus = bus;
/** @const */
this.pic = cpu.devices.pic;
this.ints = 0;
@ -247,7 +249,8 @@ function UART(cpu, port, bus)
});
this._state_skip = [
"bus",
this.bus,
this.pic,
];
}

View file

@ -23,6 +23,7 @@ var
*/
function VGAScreen(cpu, bus, vga_memory_size)
{
/** @const */
this.bus = bus;
this.vga_memory_size = vga_memory_size;
@ -40,13 +41,13 @@ function VGAScreen(cpu, bus, vga_memory_size)
* Number of columns in text mode
* @type {number}
*/
this.max_cols = 0;
this.max_cols = 80;
/**
* Number of rows in text mode
* @type {number}
*/
this.max_rows = 0;
this.max_rows = 25;
/**
* Width in pixels in graphical mode
@ -97,18 +98,6 @@ function VGAScreen(cpu, bus, vga_memory_size)
/** @type {number} */
this.text_mode_width = 80;
this.plane0;
this.plane1;
this.plane2;
this.plane3;
// 4 times 64k
this.vga_memory = null;
this.svga_memory = null;
this.svga_memory16 = null;
this.svga_memory32 = null;
this.svga_enabled = false;
/** @type {number} */
@ -225,18 +214,8 @@ function VGAScreen(cpu, bus, vga_memory_size)
}
this.svga_memory = new Uint8Array(this.vga_memory_size);
this.svga_memory16 = new Uint16Array(this.svga_memory.buffer);
this.svga_memory32 = new Int32Array(this.svga_memory.buffer);
this.vga_memory = new Uint8Array(this.svga_memory.buffer, 0, 4 * VGA_BANK_SIZE);
this.plane0 = new Uint8Array(this.svga_memory.buffer, 0 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane1 = new Uint8Array(this.svga_memory.buffer, 1 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane2 = new Uint8Array(this.svga_memory.buffer, 2 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane3 = new Uint8Array(this.svga_memory.buffer, 3 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.set_size_text(80, 25);
this.update_cursor_scanline();
this._state_restore();
var me = this;
io.mmap_register(0xA0000, 0x20000,
@ -249,31 +228,32 @@ function VGAScreen(cpu, bus, vga_memory_size)
function(addr) { return me.svga_memory_read32(addr); },
function(addr, value) { me.svga_memory_write32(addr, value); }
);
/** @const */
this._state_skip = [
"bus",
"svga_memory16",
"svga_memory32",
"vga_memory",
"plane0",
"plane1",
"plane2",
"plane3",
];
};
VGAScreen.prototype._state_restore = function()
{
this.svga_memory16 = new Uint16Array(this.svga_memory.buffer);
this.svga_memory32 = new Int32Array(this.svga_memory.buffer);
/** @const */ this.svga_memory16 = new Uint16Array(this.svga_memory.buffer);
/** @const */ this.svga_memory32 = new Int32Array(this.svga_memory.buffer);
this.vga_memory = new Uint8Array(this.svga_memory.buffer, 0, 4 * VGA_BANK_SIZE);
/** @const */ this.vga_memory = new Uint8Array(this.svga_memory.buffer, 0, 4 * VGA_BANK_SIZE);
this.plane0 = new Uint8Array(this.svga_memory.buffer, 0 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane1 = new Uint8Array(this.svga_memory.buffer, 1 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane2 = new Uint8Array(this.svga_memory.buffer, 2 * VGA_BANK_SIZE, VGA_BANK_SIZE);
this.plane3 = new Uint8Array(this.svga_memory.buffer, 3 * VGA_BANK_SIZE, VGA_BANK_SIZE);
/** @const */ this.plane0 = new Uint8Array(this.svga_memory.buffer, 0 * VGA_BANK_SIZE, VGA_BANK_SIZE);
/** @const */ this.plane1 = new Uint8Array(this.svga_memory.buffer, 1 * VGA_BANK_SIZE, VGA_BANK_SIZE);
/** @const */ this.plane2 = new Uint8Array(this.svga_memory.buffer, 2 * VGA_BANK_SIZE, VGA_BANK_SIZE);
/** @const */ this.plane3 = new Uint8Array(this.svga_memory.buffer, 3 * VGA_BANK_SIZE, VGA_BANK_SIZE);
/** @const */
this._state_skip = [
this.bus,
this.svga_memory16,
this.svga_memory32,
this.vga_memory,
this.plane0,
this.plane1,
this.plane2,
this.plane3,
];
this.bus.send("screen-set-mode", this.graphical_mode || this.svga_enabled);

View file

@ -125,6 +125,8 @@ function VirtIO(cpu, filesystem)
});
this.irq = 0xC;
/** @const */
this.pic = cpu.devices.pic;
this.queue_select = 0;
@ -136,7 +138,7 @@ function VirtIO(cpu, filesystem)
this.queue_size = 32;
this.queue_address = 0;
/** @const */
this.memory = cpu.memory;
for(var i = 0; i < 128; i++)
@ -156,10 +158,15 @@ function VirtIO(cpu, filesystem)
}
// should be generalized to support more devices than just the filesystem
/** @const */
this.device = new Virtio9p(filesystem);
this.device.SendReply = this.device_reply.bind(this);
this._state_skip = ["memory", "pic"];
this._state_skip = [
this.memory,
this.pic,
this.device,
];
this._state_restore = function()
{
this.device.SendReply = this.device_reply.bind(this);