📄 todo
字号:
-*- text -*-$ echo "def 0 1 main 'A' remit 0 ;" | idelrun1.27: Unresolved reference to remitshouldn't that have the program name initially?go through all uses of word_size and see which should change to bytes_per_word(man, that's irritating)also look at pointer arithmetic using data-space addresses (same reason)same for word_bits (geez)figure out why that one test case breaks on other systemsdoes it still?profiler should output some form of basic-block location as identifierpicking superinstructions from higher-order sequence countssuperinstructions would generalize better if you didn't usethe specialized versions for DROP, LOCAL, and BRANCHi think this'd be a better approach to combining superinstructions andspecialization:- explicitly link specializations to their prototype in the opcodes file- main codegen.c code doesn't know about specializations (this is good also because it makes it easier to add a native backend)- opcodes.awk generates checks in peep*.inc- the way those checks work: - first we look for a combo - if found, we look for a specialization of *that* - if not, we look for a specialization of the starting instruction - if that's found, we can then look for a combo on that- hopefully we can organize it all so the look-fors are just tail recursive calls into the basic emitters (conceptually)delay generating RETURN instructions since we might want TAILCALLinstead, etc. (always generating RETURN at the end of a defn usesmore space and sometimes splits up a basic block, e.g. in the fibbenchmark)get IDIV0 and IMOD0 to automatically use the right logic by checkingwhich way this c compiler roundsadd explicit checks that the stuff in idel_porting.h actually worksright for the particular compiler the system's built underremove all dynamic mallocingfind a 64-bit system to develop this on. it's obviously not going towork at first with all the casts of pointers to (i32).read p2p book chapter on resource managementcamram mailing list?get the codegen to break up too-long code paths so fuel checks happenmore often (at a configurable level). this would be less needed if wehad the fuel checks subtract a proportional amount of fuel, instead ofdecrementing by 1.test borednet before releasingread about ajantamore benchmark ideas: spellchecking with tries (sort of needs a standard dictionary + a second input source) bignum arithmetic (too much work for now) lz compression (too much work for now) lexing (but wc sort of does that) lifeanother optimization:In code like { x -- y if x foo bar then }we can notice that there are no more references to x after the callto foo (since we generate in reverse order), and insert a DROP at that point (assuming we didn't already generate the DROP after thecurrent position -- we'd have to spit them out lazily on both branchesof the IF).a ``SWAP -'' instruction might be worthwhilethen negation would be a simple macro: ``0 SWAP -''(right now it'd have to be ``-1 xor 1 +'' or ``{ n -- 0 n - }'')ironically, the same goes for < and u< so how about a SWAP instruction?i have been thinking of PICK and ROLL (with static operands)...design capability stuffstrawman:- each vm comes with a 16-entry key store- key invocation works like this: - you supply some range of addresses for each of parameter and result, for each kind of address space: - stack: i top elements (static) - fp stack: j top elements (static) (TBD) - keystore: k bottommost elements (static) - store: [m..n] (dynamic from the stack) (what about read vs. read/write vs. write? keykos did copying because you could get sharing with explicit node manipulations if you really wanted it.) (word aligned?)- to create a gate key: - describe it statically with signature and defn # - perform an instruction that takes 1 parameter (call it p) off the stack and creates a new key in the keystore (which element?)- to run an invoked gate key: - the target VM needs to have space for its arguments - we could require it to have space available for any of its entry points before it can become `available'... or check at invocation time - start with the supplied stuff on the stack and in the keystore, plus p on top of the stack - there are fetch and store instructions that work within the data blocks supplied (or we could copy blocks between spaces...) - return from the defn to go back to the caller - how to do coroutines? maybe we should have tail-invoke...- other keystore ops: - copy - roll- how do basic vm resources get reified?- rights amplification?- factories?- exceptions?- how do we safely delete an object? so there's no dangling key? i'm thinking each key has a link threaded through it of all the keys referring to the same object... (this implies that writing to a slot in the keystore has memory-management overhead.) alternatively we could use handles. but then we still need to reclaim the handle name eventually.- make sure you can port ERTP to it why don't we start with the mintmaker example mintmaker make-purse purse get-balance sprout depositproblem: our keys are more like functions than objects, with a staticsignature. i thought that was okay, but how do you *conveniently* domultiple operations like with the purse? you could invoke the pursewith a selector and get back another key that you then invoke. seemspainful. maybe we should avoid static signatures after all. or wecould have extra complexity -- model that stuff at the builtin level.i.e. give invocation an extra argument that's *always* the `messagenumber'. ok, if we do, then how to bind the methods together when wemake a new key?general note on problems and opportunities relative to keykos: wedon't have memory mapping but we do have complete control over thebinary code.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -