Another chapter in the never-ending AppDomain security saga.
If a computer goes to sleep while SourceGen is running with a project
open, life gets confusing when the system wakes up. The keep-alive
timer fires and a ping is sent to the remote AppDomain, successfully.
At the same time, the lease expires on the remote side, and the objects
are discarded (apparently without bothering to query the ILease object).
This failure mode is 100% repeatable.
Since we can't prevent sandbox objects from disappearing, we have to
detect and recover from the problem. Fortunately we don't keep any
necessary state on the plugin side, so we can just tear the whole
thing down and recreate it.
The various methods in ScriptManager now do a "health check" before
making calls into the plugin AppDomain. If the ping attempt fails,
the AppDomain is "rebooted" by destroying it and creating a new one,
reloading all plugins that were in there before. The plugin binaries
*should* still be in the PluginDllCache directory since the ping failure
was due to objects being discarded, not AppDomain shutdown, and Windows
doesn't let you mess with files that hold executable code.
A new "reboot security sandbox" option has been added to the DEBUG
menu to facilitate testing.
The PluginManager's Ping() method gets called more often, but not to
the extent that performance will be affected.
This change also adds a finalizer to DisasmProject, since we're relying
on it to shut down the ScriptManager, and it's relying on callers to
invoke its cleanup function. The finalizer throws an assertion if the
cleanup function doesn't get called.
(Issue #82)
Changed "Use Keep-Alive Hack" to "Disable Keep-Alive Hack" to emphasize
that it defaults to enabled. Added a menu item for "Disable Security
Sandbox". Added a warning to both that tells the user that they must
reopen the current project for the change to take effect.
Note neither of these is persisted in app settings.
This is still an "experimental" feature, but it's getting expanded
a bit. The implementation now lives in its own class. An "export"
feature that generates SGEC data has been added. The file extension
has been changed from ".sgec" to ".txt" to make it simpler to edit
under Windows.
On the 65816, 16-bit data access instructions (e.g. LDA abs) are
expanded to 24 bits by merging in the Data Bank Register (B). The
value of the register is difficult to determine via static analysis,
so we need a way to annotate the disassembly with the correct value.
Without this, the mapping of address to file offset will sometimes
be incorrect.
This change adds the basic data structures and "fixup" function, a
functional but incomplete editor, and source for a new test case.
If you double-click on the opcode of an instruction whose operand is
an address or equate, the selection jumps to that address. This
feature is now available in the Navigate menu, with the keyboard
shortcut Ctrl+J.
While testing the feature I noticed that the keyboard focus wasn't
following the selection, so if you jumped to an address and then
used the up/down arrows, you jumped back to the previous location.
(This was true when double-clicking an opcode to jump; it was just
less noticeable since the next action was likely mouse-based.) This
has been fixed by updating the ListView item focus when we jump to a
new location.
See also issue #63 and issue #72.
If you double-click a project symbol declaration, the symbol editor
opens. I found that I was double-clicking on the comment field and
typing with the expectation that the comment would be updated, but
it was actually setting the initial focus to the label field.
With this change the symbol editor will focus the label, value, or
comment field based on which column was double-clicked.
The behavior for Actions > Edit Project Symbol and other paths to the
symbol editor are unchanged.
Also, disabled a wayward assert.
SourceGen Edit Commands is a feature that allows you to generate
commands into a file and have SourceGen apply them to the current
project. I'm not expecting this to be used by anyone but me, so
for now I'm just adding an entry to the debug menu that can read
comments out of a file.
Also, fixed a bug in the re-centering min/max code that prevented
it from working on trivial shapes.
Also, renamed the atari-avg visualizer to atari-avg-bz, with the
expectation that one day somebody might want to create a variant
for newer games.
The tool allows you to cut a piece out of a file by specifying an
offset and a length. A pair of hex dumps helps you verify that the
positions are correct.
Also, minor cleanups elsewhere.
- Show the full path in the tooltip for the two "recent project"
buttons shown on the launch panel.
- Reset the app title bar and status bar contents when the project
is closed.
Correct handling of local variables. We now correctly uniquify them
with regard to non-unique labels. Because local vars can effectively
have global scope we mostly want to treat them as global, but they're
uniquified relative to other globals very late in the process, so we
can't just throw them in the symbol table and be done. Fortunately
local variables exist in a separate namespace, so we just need to
uniquify the variables relative to the post-localization symbol table.
In other words, we take the symbol table, apply the label map, and
rename any variable that clashes.
This also fixes an older problem where we weren't masking the
leading '_' on variable labels when generating 64tass output.
The code list now makes non-unique labels obvious, but you can't tell
the difference between unique global and unique local. What's more,
the default type value in Edit Label is now adjusted to Global for
unique locals that were auto-generated. To make it a bit easier to
figure out what's what, the Info panel now has a "label type" line
that reports the type.
The 2023-non-unique-labels test had some additional tests added to
exercise conflicts with local variables. The 2019-local-variables
test output changed slightly because the de-duplicated variable
naming convention was simplified.
Added serialization of non-unique labels to project files.
The address labels are stored without the non-unique tag, because we
can get that from the file offset. (If we stored it, we'd need to
extract the value and verify that it matches the offset.) Operand
weak references are symbolic, and so do include the tag string.
We weren't validating symbol labels before. Now we are.
This also adds a "NonU" filter to the Symbols window so the labels
can be shown or hidden as desired.
Also, added source for a first pass at a regression test.
It's too easy to hit Escape after making a bunch of changes, so
now we ask for confirmation.
(Might make sense to make this strictly an Esc guard, and not
pester the user if they actually hit the Cancel button or close
box. I'm not convinced though; Esc+Enter isn't terrible.)
Jumps to the first offset associated with the change at the top of
the Undo stack. We generally jump to the code/data offset, not the
specific line affected. It's possible to do better (and we do, for
Notes), but probably not worthwhile.
As noted in issue #52, the side panels can't be resized once the
ListView gets focus. The root of the problem is a workaround for a
selection problem that involves catching the Item Container
Generator's Status Changed event, and setting an item's focus. It
appears that changing the size of the ListView causes the
StatusChanged event to fire, which cause the handler to grab the
focus, which causes the splitters to stop moving after one step.
This change adds a workaround that prevents the original workaround
from doing anything while a splitter is in the process of being
dragged. It doesn't solve all problems -- you can't move the
splitters more than one step with the keyboard -- but it allows them
to be dragged around with the mouse.
There's got to be a better way to deal with this.
The fix for Shift+F3 required briefly switching the code list view
to single-select mode. Unfortunately, while in that mode the
control throws an exception if you touch SelectedItems (plural)
rather than SelectedItem (singular), and in an unusual case the
selection-changed event handler was doing just that.
If we detect a problem that requires intervention during loading,
e.g. we find unknown elements because we're loading a file created
by a newer version, default to read-only mode.
Read only mode (1) refuses to apply changes, (2) refuses to add
changes to the undo/redo list, and (3) disables Save/SaveAs. The
mode is indicated in the title bar.
Also, flipped the order of items in the title bar so that "6502bench
SourceGen" comes last. This allows you to read the project name in
short window title snippets. (Visual Studio, Notepad, and others
do it this way as well.)
Not a huge improvement, but things are slightly more organized, and
there's a splash of color in the form of a border around the text
describing the format of code and data lines.
Added an "IsConstant" property to Symbol.
Mark the "info" window as read-only.
When the project closes, clear the contents of the Symbols and
Notes windows.
Clarify some Apple II I/O definitions.
This adds a window that displays all of the instructions for a
given CPU in a summary grid. Undocumented instructions are
included, but shown in grey italics.
Also, tweaked AppSettings to not mark itself as dirty if a "set"
operation doesn't actually change anything.
Implemented show/hide mechanic, using a button on the right side of
the status bar to show status and to trigger un-hide.
Also, show I/O direction in project symbols editor list.
This converts the "problem list viewer" tool to a grid that appears
below the code list view when non-empty. Not all messages are
problems, so it's being renamed to "message list".
Most of SourceGen uses standard WPF controls, which get their default
style from the system theme. The main disassembly list uses a
custom style, and always looks like the Windows default theme.
Some people greatly prefer white text on a black background, so we
now provide a way to get that. This also requires muting the colors
used for Notes, since those were chosen to contrast with black text.
This does not affect anything other than the ListView used for
code, because everything else can be set through the Windows
"personalization" interface. We might want to change the way the
Notes window looks though, to avoid having glowing bookmarks on
the side.
If you select a local variable, double-click on a reference entry,
and then hit "back", you aren't taken back to the correct place in
the local variable table. This is annoying if you're trying to
explore how a local variable is used.
The NavStack Location object now has a "line delta" that can be
applied to position the selection correctly. This isn't stable
across undo/redo, but it solves the common cases.
This makes LineListGen's "Top" class redundant, so uses of that have
been replaced with Location.
The Find box now has forward/backward radio buttons. Find Next
searches forward, and Find Previous searches backward, regardless
of the direction of the initial search.
The standard key sequence for "find previous" is Shift+F3. The WPF
ListView has some weird logic that does something like: if you hit
a key, and the selection changes, and the shift key was held down,
then you must have meant to select a range. So Shift+F3 often (but
not always) selects a range. I think this might be fixable if I can
figure out how ListView keeps track of the current keyboard
navigation position (which is not the same as the selection). For
now I'm working around the problem by using Ctrl+F3 to search.
Yay WPF.
We were changing the control template for lines with long comments
and notes, matching the default Win10 style. This got ugly when a
non-default theme was being used, particularly "dark" themes,
because the long-comment lines looked significantly different from
everything else.
We now fully specify the style for the ListView and ListViewItems,
which means everybody's main window now looks like the default Win10
style. Which is unfortunate, but significantly easier than creating
a full set of theme-specific styles.
We now specify black text for highlighted address/label fields,
because they otherwise become illegible when we apply our background
highlight color. In the Notes window, we set the background of
un-highlighted entries to white, so that we can always read it with
black text.
Addresses issue #50.
Implement multi-byte project/platform symbols by filling out a table
of addresses. Each symbol is "painted" into the table, replacing
an existing entry if the new entry has higher priority. This allows
us to handle overlapping entries, giving boosted priority to platform
symbols that are defined in .sym65 files loaded later.
The bounds on project/platform symbols are now rigidly defined. If
the "nearby" feature is enabled, references to SYM-1 will be picked
up, but we won't go hunting for SYM+1 unless the symbol is at least
two bytes wide.
The cost of adding a symbol to the symbol table is about the same,
but we don't have a quick way to remove a symbol.
Previously, if two platform symbols had the same value, the symbol
with the alphabetically lowest label would win. Now, the symbol
defined in the most-recently-loaded file wins. (If you define two
symbols with the same value in the same file, it's still resolved
alphabetically.) This allows the user to pick the winner by
arranging the load order of the platform symbol files.
Platform symbols now keep a reference to the file ident of the
symbol file that defined them, so we can show the symbols's source
in the Info panel.
These changes altered the behavior of test 2008-address-changes,
which includes some tests on external addresses that are close to
labeled internal addresses. The previous behavior essentially
treated user labels as being 3 bytes wide and extending outside the
file bounds, which was mildly convenient on occasion but felt a
little skanky. (We could do with a way to define external symbols
relative to internal symbols, for things like the source address of
code that gets relocated.)
Also, re-enabled some unit tests.
Also, added a bit of identifying stuff to CrashLog.txt.
Added a Width column to the list in the project symbol editor.
Changed the local variable table editor and the project symbol editor
to use DataGrid instead of ListView. This gets us easy sorting on
arbitrary columns. The previous code was reloading the display list
after every change; now we just add/edit/remove individual items,
which helps keep the list position and selection stable.
The analyzer sometimes runs into things that don't seem right, like
hidden labels or references to non-existent symbols, but has no way
to report them. This adds a problem viewer.
I'm not quite ready to turn this into a real feature, so for now it's
a free-floating window accessed from the debug menu.
Also, updated some documentation.
Split "edit local variable table" into "create" and "edit prior".
The motivation is to allow the user to make changes to the most
recently defined table without having to go search for it. Having
table creation be an explicit action, rather than something that
just happens if you edit a table that isn't there, feels reasonable.
Show table offset in LV table edit dialog, so if you really want
to go find it there's a (clumsy) way to do so.
Increased the maximum width of a variable from 4 to 8. (This is
entirely arbitrary.)
Ported the column width stuff from EditAppSettings, which it turns
out can be simplified slightly.
Moved the clipboard copy code out into its own class.
Disabled "File > Print", which has never done anything and isn't
likely to do anything in the near future.
Also, added a note to 2019-local-variables about a test case it
should probably have.
Variables are now handled properly end-to-end, except for label
uniquification. So cc65 and ACME can't yet handle a file that
redefines a local variable.
This required a bunch of plumbing, but I think it came out okay.
String operands used to be simple -- each line had 62 characters
plus two hard-coded non-ASCII delimiters -- but now we're mixing
character and hex data, so we can't use simple math to tell where
the lines will break. We want to render them and keep the result
around until some dependency changes, e.g. different delimiters
or a change to the pseudo-op table.
Also, cleaned up LineListGen a little. It had some methods that
were declared static because they were expected to be shared, but
that never happened.
Also, fixed a bug in GatherEntityCounts where multi-line items were
being scanned multiple times.
- MakeDist now copies CommonWPF.dll.
- Spent a bunch of time tracking down a null-pointer deref that only
happened when you didn't start with a config file. Fixed.
- The NPE was causing the program to exit without any sort of useful
diagnostic, so I added an uncaught exception handler that writes
the crash to a text file in the current directory.
- Added a trace listener definition to App.config that writes log
messages to a file, but it can't generally be enabled at runtime
because you can't write files from inside the sandbox. So it's
there but commented out.
- Made the initial size of the main window a little wider.