libera/#clasp - IRC Chatlog
Search
7:35:22
karlosz
drmeister: i tried making it so that referencing the literal vector in C++ doesn't go through aref. it seems to build and everything fine but then when i run it i get some bizarro error about not enough arguments somehow... i'm worried i just did something dumb and messed up some smart pointer or raw pointer rleated array coercion thing
7:35:26
karlosz
what i have is here: https://github.com/karlosz/clasp/commit/717957d03e5ec8ee08a603d184cc43e044866d36
13:28:54
drmeister
::notify karlos I don't see anything wrong with your literals optimization in your branch. I also don't see that long has been implemented in the stuff I pulled. I'll run some tests to see if I can get LONG to compile and run.
13:41:21
drmeister
Could you guys rearrange things so that disassemble for bytecode is available in clasp early?
13:46:23
drmeister
Pull the vm instruction declarations into a separate file and declare them with their length as in (defcodes (+ref+ 2) ...). Then everything is in one place. You can use those lengths as sanity checks.
14:21:07
drmeister
The problem I'm hitting isn't that LONG was missing - it's that we are trying to stick the decimal value 288 into a vector of bytes
14:35:30
drmeister
https://github.com/clasp-developers/clasp/blob/vm/src/lisp/kernel/cmp/bytecode-compile.lisp#L888
14:43:05
drmeister
You have emit-const - that looks like a wrapper around assemble to handle +long+ cases.
15:11:56
drmeister
I could improve the debugging experience if we had the bytecode disassembler available.
15:12:47
drmeister
If there were a bad opcode we could disassemble the current bytecode module with PC addresses and see where PC is relative to that.
15:15:12
drmeister
I also temporarily bind *print-circle* in the C++ backtrace function so backtraces don't blow up
15:23:19
drmeister
https://github.com/clasp-developers/clasp/blob/vm/src/lisp/kernel/cmp/bytecode-compile.lisp#L947
15:32:28
drmeister
I think it might be more sane to add an extra argument to parse_key_args to indicate aok-p
15:35:10
Bike
::notify karlosz yeah my confusion about entry-close unwinding stack leaked into GO there. oops. i might have to fuss with it some more to make it restore during C++ unwind as well
15:35:32
drmeister
A LONG prefix for an instruction can mean anything we want - right? We could make it take any combination of uint8_t and uint16_t arguments.
15:35:49
drmeister
Bike: How do you feel about the parse_key_args having an extra argument to indicate aok-p
15:38:04
Bike
we were going to have the high bit indicate aokp, and then the low seven be the actual count (karlosz said one's complement, but i don't think that would add anything)
15:38:22
Bike
using negation (two's complement) doesn't work anyway since you can have zero keyword parameters with &allow-other-key
15:39:06
Bike
to be clear, that's parameters, like variables after &key. it doesn't affect how many _arguments_ the function can take
15:39:26
Bike
i don't think we have any functions with over a hundred parameters. sometimes they get a lot of _arguments_ but just in a &rest list
15:39:30
drmeister
Right - but are there functions out there that take more than 127 keyword parameters?
15:41:11
Bike
just to be clear about what i mean - with what i'm imagining, aokp = (thing & 0x80) and nkeys = (thing & 0x7f). with one's complement, it would be aokp = (thing = 0x80) and nkeys = ~(thing & 0x7f)
15:48:26
drmeister
In cases where (assemble context OPCODE ...) generates bad code I'm replacing it with (emit-OPCODE context ...)
15:49:04
Bike
right, because it's an ub8 vector. i think karlosz mentioned changing the vm.lisp machine to use an sb7 vector instead a while back, but i am not sure
15:50:14
drmeister
Regarding the LONG prefix. I know we talked about LONG meaning all args are LONG - but it doesn't need to be that. We have complete control over what LONG means because the LONG prefix dispatches on the following long-sub-opcode and there is special case code for each long-sub-opcode
15:51:18
Bike
Not since karlosz got multibyte labels working, which was the main reason we'd want signed numbers in there
15:51:27
drmeister
Is 1's complement better or worse than 2's complement in the rare cases that it comes up?
15:51:50
Bike
the problem with 2's complement is there's no negative zero, so &key and &key &allow-other-keys can't be encoded distinctly
15:52:01
Bike
Do you have something in mind for long here? I kind of figured we'd make every argument long because that's the most general, and because I'd expect long to be rare so if it takes up more space that's ok
15:54:11
drmeister
I was thinking if I added another argument for aok-p then that could be a single byte in any situation.
15:56:34
drmeister
It makes more sense that we have a normal (short argument) instruction and a long instruction.
16:00:17
Bike
that's good. i think getting through self build covered most of the really terrible bugs, so now it's more obscure stuff
16:08:37
drmeister
(defun foo (*stupid-special-variable*) ...) is equivalent to (defun foo (var) (let ((*stupid-special-variable* var)) ...) if it's already special - no?
16:10:01
Colleen
karlosz: Bike said 34 minutes, 51 seconds ago: yeah my confusion about entry-close unwinding stack leaked into GO there. oops. i might have to fuss with it some more to make it restore during C++ unwind as well
16:12:59
drmeister
Then the only problem we have is special parameters in loop. I could change the loop code so we don't use them and you guys can fix it later.
16:18:59
drmeister
karlosz: If you read back you will see that I put a sanity check in ASSEMBLE to check that the values are in 0..255
16:19:33
drmeister
This is my Saturday morning push to see how far we can get with bytecode-compile.lisp
16:19:55
Bike
shouldn't be too terrible... we can still use bind-required-args and stuff, and then we can just special bind right after each binding (so subsequent bindings have it)
16:20:08
Bike
and keep track of how many are special and generate that many unbinds just before the return
16:20:31
drmeister
There's little that is more relaxing and rewarding to me than a repetitive, boring task that slowly advances a project.
16:22:21
drmeister
unexpected type for object 0x7fb5e9ac032b givenTyp 5 could not find expectedTyp 790 because symbol was not defined
16:27:23
Bike
Let's see... yes and no. It uses process-lambda-list but ignores the va-rest flag, so it'll treat &va-rest as &rest
16:27:34
Bike
but then if something like vaslist-pop is in the code that might not react properly to an actual list
16:28:04
Bike
I have been trying to slowly remove all uses of &va-rest in the standard library, as cclasp gets better at doing it automatically, but we have a few left
16:29:10
drmeister
I had an idea about &rest that could improve things. What if we compile any function that has &rest with two or three cons cells on the stack?
16:30:10
yitzi
Bike: so cclasp knows to use vaslist even when &rest is there? Does it just look at the c function signature?
16:30:51
karlosz
while this is happening im thinking about how to more usefully use the opcode space we have... T should be its own instruction (its used in supplied parameter lists first of all, as well as many macros.) then probably also zero, then BYTE n to handle small constants up to 255 (which are by far the most common in e.g. bytecode compilers and the boolean stuff in Lisp)
16:31:16
karlosz
the byte instruction would make it so we'd have to shove less stuff in the literals vector and instead of an extra load we'd do a tag instead which should be faster
16:33:06
Bike
yitzi: No, I mean it will compile lisp functions to avoid consing a &rest list if it's unneeded. Nothing to do with C++. If you have (defun foo (f &rest r) (values (length r) (apply f r))) it will compile it as, to skip some details, (defun foo (f &va-rest r) (values (vaslist-length r) (vaslist-apply f r)))
16:37:42
Bike
So ideally we will never have to do &va-rest manually, and then we'd be able to remove it from lambda list parsing etc
17:16:47
drmeister
It looks like a funcallable-instance isn't being recognized as an Instance_O. It shouldn't be?
17:27:42
drmeister
That can't work because core:instance-rack expects an Instance_O and not a FuncallableInstance_O -
17:33:32
drmeister
https://github.com/clasp-developers/clasp/blob/vm/src/lisp/kernel/cmp/codegen-special-form.lisp#L61
17:35:54
drmeister
Good lord - there may be a fair amount of work to do here to either expand the bytecode compiler to generate code for these - or implement it in C++ somehow.
17:53:17
drmeister
Nothing to read/write slots within an object at a particular byte offset - do we?
17:57:48
drmeister
We are going to need some more bytecode instructions to generate bytecode for these special operators.
18:18:36
drmeister
I recommend that we add a few instructions like MEMREAD <byte-offset> | stack-top: <obj> and MEMWRITE <byte-offset> | stack-top: <obj> <value>
18:19:10
drmeister
Then we can implement codegen for special operators specific to clasp. like core:instance-read and core:instance-set
18:20:14
drmeister
https://github.com/clasp-developers/clasp/blob/vm/src/lisp/kernel/cmp/codegen-special-form.lisp#L1428
18:22:29
drmeister
We already have everything we need to calculate the offset. It would take a tagged pointer to an instance or a funcallable-instance on the stack and add a byte offset to it to get to an aligned pointer where the tagged pointer the the rack is stored and either read or write to it.