Skip to content

Commit e041c35

Browse files
Precompile now checks using physical addresses rather than XEIP (#60)
* start of work * Addresses are now invalidated if next page unexpected * Tweaks, seems to be running now * Page remap checks are now accurate
1 parent 8fea6c3 commit e041c35

File tree

3 files changed

+57
-27
lines changed

3 files changed

+57
-27
lines changed

lua/wire/zvm/zvm_core.lua

+53-12
Original file line numberDiff line numberDiff line change
@@ -402,14 +402,22 @@ function ZVM:Precompile_Finalize()
402402
if not result then
403403
print("[ZVM ERROR]: "..(message or "unknown error"))
404404
else
405-
for address = self.PrecompileStartXEIP, self.PrecompileXEIP-1 do
405+
-- This should guarantee the physical addresses for things.
406+
local page = self:GetPageByIndex(math.floor(self.PrecompileStartXEIP/128))
407+
local precompileStartPEIP = self.PrecompileStartXEIP
408+
local precompilePEIP = self.PrecompileXEIP
409+
if page.Remapped == 1 then
410+
precompileStartPEIP = page.MappedIndex*128+self.PrecompileStartXEIP%128
411+
precompilePEIP = precompileStartPEIP+(self.PrecompileXEIP-self.PrecompileStartXEIP)
412+
end
413+
for address = precompileStartPEIP, precompilePEIP-1 do
406414
if not self.IsAddressPrecompiled[address] then
407415
self.IsAddressPrecompiled[address] = { }
408416
end
409-
table.insert(self.IsAddressPrecompiled[address],self.PrecompileStartXEIP)
417+
table.insert(self.IsAddressPrecompiled[address],precompileStartPEIP)
410418
end
411419
setfenv(result,self.Env)
412-
self.PrecompiledData[self.PrecompileStartXEIP] = result
420+
self.PrecompiledData[precompileStartPEIP] = result
413421
end
414422

415423
return result
@@ -455,9 +463,20 @@ function ZVM:Precompile_Step()
455463
-- Check if we crossed the page boundary, if so - repeat the check
456464
if math.floor(self.PrecompileXEIP / 128) ~= self.PrecompilePreviousPage then
457465
self:Emit("VM:SetCurrentPage(%d)",math.floor(self.PrecompileXEIP/128))
458-
self:Emit("if (VM.PCAP == 1) and (VM.CurrentPage.Execute == 0) and")
459-
self:Emit(" (VM.PreviousPage.RunLevel ~= 0) then")
460-
self:Dyn_EmitInterrupt("14",self.PrecompileIP)
466+
self:Emit("if (VM.PCAP == 1) then")
467+
self:Emit("if (VM.CurrentPage.Execute == 0) and (VM.PreviousPage.RunLevel ~= 0) then")
468+
self:Dyn_EmitInterrupt("14",self.PrecompileIP)
469+
self:Emit("end")
470+
local expectedPage = self:GetPageByIndex(math.floor(self.PrecompileXEIP/128))
471+
if expectedPage.MappedIndex ~= math.floor(expectedPage.MappedIndex) then
472+
-- Bad address because MappedIndex is a float, send out an invalid address interrupt if this gets executed(it probably will in a sec)
473+
self:Dyn_EmitInterrupt(15,expectedPage.MappedIndex*128)
474+
end
475+
self:Emit("end")
476+
self:Emit("if (VM.CurrentPage.MappedIndex ~= %d) then",expectedPage.MappedIndex)
477+
-- This page wasn't the expected continuation, we should invalidate this address. (force recompile at this point)
478+
self:Emit("VM:InvalidateVirtualPrecompileAddress(VM.XEIP)")
479+
self:Dyn_EmitBreak(true)
461480
self:Emit("end")
462481
self:Emit("VM:SetPreviousPage(%d)",math.floor(self.PrecompileXEIP/128))
463482

@@ -619,8 +638,26 @@ function ZVM:Precompile_Step()
619638
return not self.PrecompileBreak
620639
end
621640

641+
-- Helper that will convert virtual => physical for you if necessary and then invalidate them.
642+
function ZVM:InvalidateVirtualPrecompileAddress(Address)
643+
local Page = self:GetPageByIndex(math.floor(Address/128))
644+
local newAddress = Address
645+
if Page.Remapped == 1 then
646+
Address = (Page.MappedIndex*128)+(Address%128)
647+
end
648+
self:InvalidatePrecompileAddress(Address)
649+
end
622650

623-
651+
-- These should be physical addresses.
652+
function ZVM:InvalidatePrecompileAddress(Address)
653+
-- Invalidate precompiled data (Moved so the address will be changed to physical if necessary)
654+
if self.IsAddressPrecompiled[Address] then
655+
for k,v in ipairs(self.IsAddressPrecompiled[Address]) do
656+
self.PrecompiledData[v] = nil
657+
self.IsAddressPrecompiled[Address][k] = nil
658+
end
659+
end
660+
end
624661

625662
--------------------------------------------------------------------------------
626663
-- VM step forward
@@ -648,9 +685,14 @@ function ZVM:Step(overrideSteps,extraEmitFunction)
648685
self.NIF = nil
649686
end
650687

688+
local address = self.XEIP
689+
if self.CurrentPage.Remapped == 1 then
690+
address = (self.CurrentPage.MappedIndex*128)+(self.XEIP%128)
691+
end
692+
651693
-- Check if current instruction is precompiled
652-
local instructionXEIP = self.XEIP
653-
if self.PrecompiledData[instructionXEIP] or overrideSteps then
694+
local instructionPEIP = address
695+
if self.PrecompiledData[instructionPEIP] or overrideSteps then
654696
-- Precompile next instruction
655697
if overrideSteps then
656698
self:Precompile_Initialize()
@@ -670,12 +712,11 @@ function ZVM:Step(overrideSteps,extraEmitFunction)
670712
-- Step clock forward (account for precompiling)
671713
self.TMR = self.TMR + 24*8000 -- + overrideSteps*9000
672714
end
673-
674715
-- Execute precompiled instruction
675716
if CLIENT then -- FIXME: hack around crash on PCALL
676-
self.PrecompiledData[self.XEIP]()
717+
self.PrecompiledData[address]()
677718
else
678-
local status,message = pcall(self.PrecompiledData[self.XEIP])
719+
local status,message = pcall(self.PrecompiledData[address])
679720
if not status then
680721
print("[ZVM ERROR]: "..message)
681722
self:Interrupt(5,1)

lua/wire/zvm/zvm_features.lua

+3-9
Original file line numberDiff line numberDiff line change
@@ -291,14 +291,6 @@ function ZVM:WriteCell(Address,Value)
291291
return false
292292
end
293293

294-
-- Invalidate precompiled data
295-
if self.IsAddressPrecompiled[Address] then
296-
for k,v in ipairs(self.IsAddressPrecompiled[Address]) do
297-
self.PrecompiledData[v] = nil
298-
self.IsAddressPrecompiled[Address][k] = nil
299-
end
300-
end
301-
302294
-- Do we need to perform page checking
303295
if self.PCAP == 1 and self.MF == 1 then
304296
-- Fetch page
@@ -351,7 +343,9 @@ function ZVM:WriteCell(Address,Value)
351343
end
352344
end
353345

354-
-- Perform I/O operation
346+
-- Invalidate precompiled data (Moved so the address will be changed to physical if necessary)
347+
self:InvalidatePrecompileAddress(Address)
348+
-- Perform I/O operation
355349
if (Address >= 0) and (Address < self.RAMSize) then
356350
self.Memory[Address] = Value
357351
else

lua/wire/zvm/zvm_opcodes.lua

+1-6
Original file line numberDiff line numberDiff line change
@@ -1206,12 +1206,7 @@ ZVM.OpcodeTable[131] = function(self) --SMAP
12061206
self:Dyn_EmitInterruptCheck()
12071207

12081208
self:Dyn_Emit("for address=IDX*128,IDX*128+127 do")
1209-
self:Dyn_Emit("if VM.IsAddressPrecompiled[address] then")
1210-
self:Dyn_Emit("for k,v in ipairs(VM.IsAddressPrecompiled[address]) do")
1211-
self:Dyn_Emit("VM.PrecompiledData[v] = nil")
1212-
self:Dyn_Emit("VM.IsAddressPrecompiled[address][k] = nil")
1213-
self:Dyn_Emit("end")
1214-
self:Dyn_Emit("end")
1209+
self:Dyn_Emit("VM:InvalidateVirtualPrecompileAddress(address)")
12151210
self:Dyn_Emit("end")
12161211
self:Dyn_Emit("else")
12171212
self:Dyn_EmitInterrupt("11","IDX")

0 commit comments

Comments
 (0)