<KipIngram>
I'm not sure exactly what you mean, but it sounds positive somehow.
<KipIngram>
Sounds "performnce oriented."
<KipIngram>
With indirect threading I can't literally inline code. But I can automatically construct super-primitives," that is a single code unit with the action of several primitives strung together.
<KipIngram>
Or I can use an assembler and go completely custom.
<KipIngram>
I think I like this idea of saving the superframe register on the return stack - with that I can use that feature to implement the error exceptions.
<veltas>
It's like the difference between ": with-xt ['] word rep ;" and ": inline 0 ?do word loop ;"
<KipIngram>
I see.
<veltas>
With indirect threading you can have a word that just starts executing from IP as machine code
<veltas>
So you can inline machine code
<KipIngram>
Hmmm. Yes, but I have to have a way to move the IP past it. I guess there would be a <n> CODE <n bytes of code> <next word> or something like that?
<KipIngram>
then the code would just end with NEXT.
<KipIngram>
So the IP would be moved past it before you jumped to it.
<veltas>
No I would set up IP in the code, have an easy macro that sets IP to the machine IP
<veltas>
It's not a CODE word it doesn't need to use NEXT imo
<KipIngram>
Ok. That makes sense too.
<KipIngram>
Sure, it has to return to the threading.
<KipIngram>
When it's done.
<KipIngram>
That means ending in NEXT.
<veltas>
It needs to carry on the colon word it is inlined within
<KipIngram>
Yes, correct.
<KipIngram>
So you move IP to the location of the next compiled cell, and then when you run NEXT it will pick up from there.
<veltas>
If the word that starts the inlined section just jumps to it, then at end of that assembly section you might be able to write something to optimise this
<KipIngram>
I don't really see the advantage of putting it inline.
<veltas>
If it's inline you don't need a header/symbol
<KipIngram>
If it's a normal primitive you jump to it. But you have to jump to it inline too.
<KipIngram>
Oh, I see.
<KipIngram>
Ok, fair point.
<KipIngram>
So no real performance advantage, but an advantage in dictionary compactness.
<KipIngram>
Yeah, that's an interesting idea.
<veltas>
At end of inline code you can have a macro that either adds to IP the size of code so far, or CALL's a routine to continue with IP = return pointer
<KipIngram>
My definition cells and code are in the same memory section anyway.
<KipIngram>
Right.
<KipIngram>
I grok it now.
<veltas>
Yes this is why I prefer inline control structures over control words that take an xt
<veltas>
Although inline words are lighter than normal words still
<KipIngram>
Sure. It's really the same thing ." does - anything can go inline as long as you know it's size.
<KipIngram>
All this stuff is seriously good fun - all the ways Forth lets you diddle and twiddle around. :-)
<veltas>
Yup
<tabemann>
all of this is alien to me, since the forth I'm working on is SRT/NCI; inlining just involves grabbing a word's definition and copying it into the code being compiled
<tabemann>
aside from certain words which combine with preceding constants
eli_oat has joined #forth
eli_oat has quit [Quit: WeeChat 2.8]
eli_oat has joined #forth
boru` has joined #forth
boru has quit [Disconnected by services]
boru` is now known as boru
<tabemann>
KipIngram, about what you were saying there about 1+, 2+, 4+, 8+
<tabemann>
in my zeptoforth I defer constants when they are initially compiled, so if the following word is one of a small number of words such as + and -, if the constants are in the right range, they can be compiled right into the instruction for the word, avoiding pushing and popping on the stack
eli_oat has quit [Quit: WeeChat 2.8]
<KipIngram>
Oh, that's interesting.
<KipIngram>
Nice idea.
<KipIngram>
Yeah, I just saw no point in all that stack commotion given the number of times I add and subtract certain values in the system.
<KipIngram>
Especially when it completely eliminates all memory access (just updates the TOS in-register).
<KipIngram>
SOOOO much more efficient.
<KipIngram>
How did you arrive at the name "zeptoforth"?
<KipIngram>
And yes - subroutine threading offers the most natural inlining of all.
<KipIngram>
Do you implement the CREATE / DOES> mechanism in zeptoforth?
<KipIngram>
If so, I'd be curious to know whether you found tht difficult to do in subroutine threading.
<KipIngram>
I go back and forth over whether I really think of subroutine threading as actual Forth.
dave0 has joined #forth
<dave0>
maw
<KipIngram>
Ok, I modified {| ... |} to make it nestable. I'm unsure if I want to use it for standard error handling, though. It would work great for handling errors. But if there's ever an error condition I want to trap that I come upon when I INSIDE ANOTHER EXCEPTION FRAME, then it wouldn't do the right thing.
<KipIngram>
So I may keep error handling apart.
<KipIngram>
I've always had a little gleam in my eye around learning how to trap memory access errors, divide by zero, and that kind of thing, and handling those within the system.
<KipIngram>
I assume that would involve hooking some interrupt.
<KipIngram>
Hey dave0.
<KipIngram>
Long time - have you been well?
<dave0>
hey KipIngram
<dave0>
yup, i've been exercising lately!
<dave0>
going for nice walks
<dave0>
KipIngram: how are you?
<KipIngram>
Good for you. I seriously need to do that. I mean, SERIOUSLY. I'm sitting around letting myself get in awful shape.
<KipIngram>
I was just thinking about that over the weekend.
<KipIngram>
Even if it's just walking and standing up from where I work and waving the little 25 pound kettle bell I keep beside me around - I'd be worlds better off.
<KipIngram>
When I bought that bell I envisioned doing that regularly and gradually working up to heavier bells.
<dave0>
oh is it an exercise thing? lift the bell like weights?
<dave0>
i just walk :-) it's good cos you're allowed to exercise outside while it's covid
<KipIngram>
A kettlebell is just a little weight with a U shaped handle on it.
<KipIngram>
You just pick it up and move it around in various ways.
<KipIngram>
One of the things I do with it is stand up and hold it in both hands in front of me. Then lift it up in front of my face and carry it around my head in a circle (so it passes behind my head).
<KipIngram>
That seems to engage most of my arms and upper body.
<dave0>
i could really work on my shoulders
<dave0>
cool
<KipIngram>
That move I just described hits the shoulders well.
<dave0>
i'm getting muscular legs but not losing any weight :-p
<dave0>
instead of getting thinner, i've built up my muscles to carry the extra weight lol
<KipIngram>
Well, muscle weighs something - even if you don't lose weight if you build muscle it will affect your shape in a good way.
<dave0>
i haven't weighed myself cos it's embarrasing :-p
<KipIngram>
I've lost a goodly little bit of weight recently.
<dave0>
nice
<KipIngram>
Yeah - I know that feeling. I'm on a good track there at the moment though. Almost below 200.
<dave0>
do you eat healthy?
<KipIngram>
Pretty healthy, yes.
<dave0>
that's as important as exercise and vice versa
<KipIngram>
Yeah.
<KipIngram>
I've cut my drinking back a good bit too. I've never been a lush, or anything, but there've been times I've taken in too many calories that way.
<dave0>
i've totally quit beer, but did i tell you i was drinking non-alcoholic beer for a while?
<dave0>
heinekin zero tastes really nice
<KipIngram>
No, we never discussed that that I recall.
<KipIngram>
So, I seem to recall you were working on a system last time we interacted. How's it coming?
<dave0>
oh like everything i did a bit and never finished it lol
<dave0>
KipIngram: there's a guy on a differnt channel "gilberth" who is making a homebrew cpu in the 50's style
<dave0>
it would be perfect for forth
<KipIngram>
:-) Yup - I know that feeling too. I got mine prett finished, but then got busy and left it sitting for a while. I'm currently "reworking" it, which really means writing it again from scratch with a willingness to raid it for code.
<KipIngram>
I'd never been exposed to the idea before I had dave0 describe his system, which basically uses "return" as the inner interpreter (so it's direct threaded). I thought it was a novel idea and was really interested in seeing how it panned out.
<KipIngram>
I thought there might be a problem with interrupts corrupting his definition space (since it's his processor stack) but it turns out that interrupts use a whole different stack space.
<KipIngram>
So as long as *he* didn't screw up his space, he should have been ok.
<KipIngram>
I would have stolen that trick if I did direct threaded systems.
<KipIngram>
But I usually go indirect.
<veltas>
mark4's x64 does this too, don't know about x4 though
<veltas>
i.e. uses ret as next
f-a has joined #forth
<KipIngram>
I wanted to put machine code and Forth "code" in the same section. I can't do that with the segments granted me by the system when the program first loads.
<KipIngram>
So, I allocate two regions of RAM, one for code and parameter space, and the other for name strings, links, and CFA/PFA pointer pairs.
<KipIngram>
My system doesn't have the CFA "just before" the content of a word.
<KipIngram>
There is the CFA pointer to some code, and then a PFA *pointer* to the parameter space.
<KipIngram>
Primary reason for doing that was so that I can have multiple entry points to a definition - I can do this:
<KipIngram>
: foo ... ... : bar ... ... ;
<KipIngram>
And nothing that happens when I add bar to the dictionary pollutes the definition sequence.
<KipIngram>
All those ... pieces are contiguous.
<KipIngram>
So anyway, I create the initial content of those regions in my assembly .text and .data sections, and then at startup I copy those regions into the two allocated regions. It's all relocatable anyway - all of my cells contain offsets from the start of the region, and I use registers r15 and r14 to point to the regions.
<KipIngram>
So my code adds r15 or r14 to each scooped up value appropriately.
<KipIngram>
So when I jump to that I no longer have any permission limitations on what I can do with the memory.
<KipIngram>
I allocate the regions read/write/execute.
<KipIngram>
COLD will jump back down to the initially loaded code and re-copy the sections, using the same memory regions as before.
<KipIngram>
It took a bit of diddling to get that to work.
<KipIngram>
And at least the .text section is write protected, so there's some protection from corrupting the initial image.
<KipIngram>
"There are, however, some architectures and/or operating systems that forbid a program to generate and execute code at runtime. We consider this restriction arbitrary and consider it poor hardware or software design. Implementations of programming languages such as FORTH, Lisp, or Smalltalk can benefit significantly from the ability to generate or modify code quickly at runtime.
<KipIngram>
"
<KipIngram>
Ooops - sorry.
f-a has quit [Quit: leaving]
dave0 has joined #forth
<dave0>
maw
tech_exorcist has joined #forth
<KipIngram>
Morning.
gravicappa has quit [Ping timeout: 240 seconds]
<KipIngram>
dave0: Did you see the link siraben posted for us?
<KipIngram>
More on ROP.
<siraben>
KipIngram: Ben Lynn's website is a gold mine for CS stuff, really smart guy
<dave0>
KipIngram: ah nope, have you still got it?
<KipIngram>
And I agree with his conclusion that execution protection is a futile gesture that just complicates life for some people (like Forth developers) without really securing the landscape.
<siraben>
the RTS is a single file ANSI C program
<siraben>
Right.
<siraben>
it's really annoying to do some stack related things on modern systems
<KipIngram>
Well, just the notion of wanting an assembler and to create new code words is ruled out from the jump.
<dave0>
i recognize this page
gravicappa has joined #forth
<KipIngram>
I just completely bypassed all that by copying my system off to newly allocated blocks that are wide open permission-wise.
<KipIngram>
Never mind that block I got loaded in.
<dave0>
KipIngram: i think it's lucky that there is JIT things like the java runtime thing, so hopefully it will always be possible to enable writing code on the fly and executing it
<dave0>
javascript JIT too
<KipIngram>
Yeah.
<KipIngram>
Well, it has to be *possible*, from a hardwre perspective, because the system needs to load programs.
<dave0>
oh yeah didn't think of that!
<KipIngram>
You ever hear of capabilities? I ran across htem decades ago, and they seemed like a good way to manage access.
<KipIngram>
Basically it's a setup where items that can serve as addresses have some special bits set, that you yourself can't just "set." They're set by the privileged part of the system.
<KipIngram>
So you can't just make up a pointer and access any part of memory.
<KipIngram>
You have to have a "capability" for it.
<KipIngram>
And there are rules around creating, copying, and sharing capabiliies.
<KipIngram>
So I might have read/write access to some memory range, and I could share a capability with you that only provided read access.
<KipIngram>
The permision bits are actually "in the computer word," and are managed by secure hardware.
<siraben>
KipIngram: oh wow, that's crazy
<siraben>
the TI-84+ has a sorta similar restriction, the first page of RAM is read-only
<siraben>
(Z80)
<X-Scale>
Speaking of JIT, are there some Forth implementations affected by this Apple Silicon (M1 chip) security limitation that's affecting MIT Scheme ?
<X-Scale>
"No support for Apple silicon: At this time, we are unable to support new macs using Apple's silicon (the M1 chip). Although we support the ARM architecture it's based on, Apple's design uses W^X restrictions that conflict with the way that MIT/GNU Scheme manages memory."
<X-Scale>
"Our native-code implementation requires both write and execute permissions on memory, and fixing that is a significant redesign that's unlikely to happen in the near future."
f-a has joined #forth
<proteusguy>
X-Scale, probably a forth written for a Harvard architecture could port to the M1. But I wonder how much other undocumented proprietary nonsense is in those machines...
<dave0>
i think indirect threading would work
<dave0>
it's amazing how forth can adapt to those things
<siraben>
X-Scale: oof, didn't know MIT Scheme didn't run on M1
<X-Scale>
proteus-guy: indeed. Digital jails implemented in hardware. It's a dangerous trend.
<siraben>
ever since T2 was introduced, Linux on Mac has been a pipe dream
<siraben>
technically yes you can boot a distro on it, but good luck getting all the hardware to work
<veltas>
It's kind of an interesting limitation, I don't know about MIT/GNU Scheme but Forths can certainly be written to work around this without any particular penalty
<dave0>
all these hardware mitigation things because of a bogus language C where the real problem is
f-a has quit [Quit: leaving]
<veltas>
X-Scale: The permissions are per-thread
<veltas>
You could have a thread for dispatching modifications to the dictionary
<veltas>
"avoid accessing the same memory region from multiple threads. Giving multiple threads access to the same memory region opens up a potential attack vector, in which one thread has write access and another has executable access to the same region."
<veltas>
broken by design lol
<veltas>
I'm sure there are other work-arounds
<KipIngram>
Yeah, sounds like Apple's going whole hog down the wrong road.
<KipIngram>
dave0: Yes, you could still put a Forth system together. You just wouldn't be able to easily create new primitives.
<KipIngram>
veltas: Ah, ok, that is better. You don't really need to write annd execute so close together that different threads couldn't handle it.
<veltas>
Might also be an mmap solution, map two different address ranges to one block of memory, have different permissions on those ranges
<KipIngram>
I worked around it as I indicated earlier. The main difficulty was getting some of the initial variable contents set, because the actual value of a variable lives in the section that was .text at startup. Writing not allowed.
<veltas>
Would not be shocked if enough stuff stops working they just roll it back and allow RWX in future
<KipIngram>
So I had to copy the images to their new home and then set the values there.
<KipIngram>
It's just bizarre that they cling so hard to these policies when they don't really represent a significant barrier to hacking.
<KipIngram>
That paper siraben posted earlier explains how easy it is to defeat.
<veltas>
By default code is read-only, and any JIT code will still be modified, albeit with more effort, so is still 'hackable' in mostly the same way
<KipIngram>
I have an example of similar stature with my employer. The decided to switch off the ability to write to USB drives on our computers.
<KipIngram>
We can still read them, but can't write.
<KipIngram>
And that means you can't work with any kind of a dev kit, can't manage books on ereaders or songs on iPods, and so on.
<KipIngram>
The stated reason for this was to prevent employees from writing important IP to portable drives and walking out with it.
<KipIngram>
But guess what/
<KipIngram>
?
<veltas>
That was my guess
<KipIngram>
Burning DVD plugged in to the USB port still works.
<KipIngram>
So, they accomplished NOTHING.
<veltas>
That's a harder though, and makes noise
<KipIngram>
Except to make using the computer for side purposes impossible.
<veltas>
You can probably SFTP stuff without them having any idea too
<KipIngram>
Yes.
<KipIngram>
We can still scp, sftp, use Dropbox, etc. etc.
<KipIngram>
So it was just done so that some executive could tell his boss that "proactive steps had been taken."
<veltas>
A lot of security policies are like this, break stuff and don't actually secure anything
<KipIngram>
Stupid corporate thing.
<KipIngram>
Right.
<KipIngram>
It's mostly for show.
<KipIngram>
I was really hacked when I realized I couldn't manage my ereader books anymore.
<KipIngram>
I mean, obviously that's a personal use.
<KipIngram>
But it's the kind of personal use that most employers don't mind.
<KipIngram>
Long as it's on your own time.
<KipIngram>
What it does is raise the chances of me buying my own computer.
<KipIngram>
Then I won't have my work computer in front of me as much, and I'll wind up doing less work.
<KipIngram>
I found a way to work around on the ereader.
<KipIngram>
I use the Calibre program to manage my library on the computer, and it has a feature called a "content server." You turn that on, and it creates a WiFi accessible website.
<KipIngram>
I can hit that with the ereader's browser and download books that way.
<KipIngram>
Which is the only truly essential capability.
<KipIngram>
But I really wish I had a good way to dick around with little development kits of various kinds.
<KipIngram>
Of course, a lot of those require Windows.
<KipIngram>
Which is just never going to happen again, in my life.
<KipIngram>
I get really agitated with vendors who only support Windows use of their products.
<KipIngram>
My work computer is MacOS, and it's... "ok."
<KipIngram>
It behaves enough like Linux that I can deal with it.
<KipIngram>
But I had to jump through some extra hoops to make this Forth work on it.
<KipIngram>
You can't really use absolute addresses of any kind in a MACH-O executable.
<KipIngram>
Everything has to be relative.
<KipIngram>
So a Forth definition as a list of addresses? No go.
<KipIngram>
So mine are lists of offsets, from the base address of the system.
<KipIngram>
I keep that address in a register, and NEXT is the first thing, it's AT that address.
<KipIngram>
So NEXT just becomes jmp r15.
<KipIngram>
(:) loads the contents of each word's CFA and then adds r15, and jumps there.
<KipIngram>
Etc.
<KipIngram>
Addresses on the stack are real addresses - it's easy enough to use absolute addresses "one level up."
<KipIngram>
But that bottom foundation layer has to do all this offset trickery.
<veltas>
My C Forth is trying to avoid so much trickery, but I am mapping to a fixed address to achieve that which has its own issues
<KipIngram>
Once I get it so it can rebuild itself, I could probably rebuild an absolute image.
<KipIngram>
I'll see if I can keep that an easily available option.
<KipIngram>
veltas: My, uh, "Forth before last" was a gcc version.
<KipIngram>
The source code was ungodly ugly.
<KipIngram>
But it worked.
<KipIngram>
The source for the last one (nasm assembly) was much cleaner, and this time it's cleaner still. I got some really nice macros put together that construct the dictionary and so forth.
cp- has quit [Quit: Disappeared in a puff of smoke]
f-a has joined #forth
gravicappa has joined #forth
<KipIngram>
veltas: are you using gcc for your Forth?
<veltas>
KipIngram: It uses GCC but not GCC specific features
<veltas>
I am using GCC to compile anyway
<veltas>
Well apart from being able to use a function pointer like a pointer, but all C compilers let you do that
<KipIngram>
I see. You aren't using gcc's pointer to label extension for your inner interpreter?
<veltas>
No
<KipIngram>
Ok. I used that in mine, so I had a really standard inner interpreter.
<veltas>
I'm trying to keep it somewhat simple, it's a tokenised representation because I don't want dictionary to be unnecessarily huge
<veltas>
I can add you to repo after work if you're interested in seeing what it looks like
<veltas>
Nothing works right now, early days
<KipIngram>
Oh, sure - I always like seeing what other folks are up to in Forth.
<veltas>
Me too
<veltas>
The idea is the file will build two different binaries, one to build the core dictionary, and a lighter one that loads the dictionary as a precompiled image
<veltas>
based on whether PREBUILD or whatever I called it is defined
dave0 has quit [Quit: dave's not here]
cp- has joined #forth
tech_exorcist has quit [Remote host closed the connection]
<KipIngram>
There are other Kip Ingrams around, but none of them seem to be in tech.
<KipIngram>
There's a fireman somewhere, and a preacher somewhere, and one other one I ran across once.
<veltas>
I have invited you to the repo whatever that means
<veltas>
It's not particularly secret, I just don't want to make it totally public until it's a bit more complete than it is right now
<KipIngram>
Totally understand.
f-a has quit [Read error: Connection reset by peer]
gravicappa has quit [Ping timeout: 240 seconds]
gravicappa has joined #forth
f-a has joined #forth
<mark4>
veltas yea i dont like making a repo public till its not embarrasing :)
jedb_ has quit [Remote host closed the connection]
<veltas>
Exactly
<veltas>
Or in my case, less embarrasing
<phadthai>
Linux would never have become popular (or useful) if people didn't jump and help improve Torvald's original messy and incomplete code :)
<neuro_sys>
Test, am I still connected?
<neuro_sys>
Yes I am.
<lispmacs[work]>
neuro_sys: no, it is a phantom signal you are getting
<neuro_sys>
Dammit
gravicappa has quit [Ping timeout: 240 seconds]
f-a has quit [Quit: leaving]
<KipIngram>
:-)
MrMobius has quit [Ping timeout: 268 seconds]
dave0 has joined #forth
<dave0>
maw
MrMobius has joined #forth
tech_exorcist has quit [Remote host closed the connection]
tech_exorcist has joined #forth
jedb has joined #forth
<KipIngram>
Hey hey hey.
<KipIngram>
Well, I guess I'll start ticking this FIND stuff in. I've cogitated on it for a good while; gotta do it sometime.
<KipIngram>
I added words PATH and FORTH earlier, and have it so on startup PATH will point to FORTH and FORTH's links are null. And FORTH properly points to the linked list.