-
go through usage of scopes and ensure all are being exited properly
-
fix native stuff
-
vm fully async
- stackless import
- stackless class init
- make
init
a contextual keyword that doesn't requirefn
in classes - user cannot access initializer (to call it again) only way is to call the class type
- remove
super.init()
and replace with calling the proxy (super()
)
- make
-
remove
__miri
feature and put args inxtask miri
instead (--filter
for running only specific tests)- should unlock
--all-features
- should unlock
-
change ptr repr to use manual vtable + static object trait
-
remove Table
named_field
, it should be reserved for methods -
move all field access/index access/etc. to delegate to the object trait
-
fix
from m import a, b, c
bug -
unify globals/global
-
remove
Ref
from name of public value types (inner should be prefix byOwned
or qualified path) -
fix
scope.params
will panic if given the wrong number of args -
comma between disassembly operands
-
rename
emit
tocodegen
-
print to configurable writer
-
allow printing disassembly (add option to compile snippet and explicitly run it -> expose
disassemble
on it) -
list indexing
-
list index oob should return None instead of error (improve error message)
-
to_index should check MIN_SAFE_INT
-
methods on builtins
-
for iter loops (list)
-
ops on builtins <<<
-
store
this
as a special register inThread
- method calls can setthis
andself
access will fetch throughthis
as opposed to slot 0 -this
can be pushed onto the stack if it needs to be saved, such as script->script function calls - native/builtin functions can also accessthis
through theirscope
as opposed to expecting it in param 0 -
fix "invalid indentation" errors in parser which should be more specific
-
all function types should have the same global type
Function
for use inis
checks -
all class types (including native) should have the same global type
Type
for use inis
checks -
class instances should walk the parent chain in
is
checks -
derive(Data)
- immutable
- non-constructible
- no methods
-
repl
- multi-line editor
-
spaces only, make better error message for tabs
-
debugger
- egui
- inspect state of VM
- call frames
- stack, accumulator
- pretty-print values (using Debug)
- step through bytecode (not necessarily source code)
-
tuples
-
generators
-
f-strings
-
is
-
in
-
exceptions (try/catch)
- script-land inheritable error type
-
inherit from native class
-
report code locations (intern spans, track in hashmap of
offset->span_id
) -
timeout feature (abort signal,
Arc<AtomicBool>
or similar) -
semicolons (
;
for stmt,;;
for block) -
codegen optimizations
- dead code elimination (using basic blocks)
- constant pool compaction
- elide previous instruction for clobbered reads
- peephole previous 2 instructions
- load + store -> mov
- load_field + call -> invoke
- (load_smi 1) + add -> add1
- specializations
- load rN -> loadN, for N in 0 to some max bound
- store rN -> storeN, for N in 0 to some max bound
-
inspect dispatch loop codegen (should be a jump table)
-
inline caching
- per-function IC
- reserve IC slot in codegen
-
quickening
https://haste.zneix.eu/wucivywofu.swift
thread.main(function: Ptr<Function>) async
push_frame(function, &[])
run().await
pop_frame()
take(self.acc)
thread.run() async
loop
frame = current()
match dispatch(frame)
Poll(future) -> self.acc = future.await
Yield -> break
thread.call(function: Ptr<Any>, args) -> Result<Value> async
match function.call(get_empty_scope(), args)
Return(value) -> value
Poll(future) -> future.await
Dispatch ->
run().await
take(self.acc)
// TODO
thread.op_call(callee, count)
trait Object
call(scope, this: Ptr<Self>, args: Args) -> Result<Call>
impl for Ptr<Function>
call(scope, this: Ptr<Function>, args: Args) -> Result<Call>
check_args?
if !has_self
scope.stack.push(this)
scope.stack.extend_from_within(args.to_range())
scope.stack.extend(frame_size - args.count - (has_self as usize))
push_frame()
enum Call
Return(value)
Poll(future)
Dispatch
can be derived or implemented manually
trait Type {
fn build(&mut ClassBuilder) -> ClassDescriptor;
}
NativeModuleBuilder
.class(str, impl Type)
users may only store userdata which is Send, so intovalue does not have to require send, because the only way to create a value is out of Send things.
public API accepts impl IntoValue
Map code offset -> span
also need to know which file we're in so we can report
LdaZero ; a = 0
Star0 ;
LdaSmi [1] ; b = 1
Star1 ;
LdaZero ; i = 0
Star2 ;
; loop:
Ldar a0 ; i < n
TestLessThan r2, [0] ;
JumpIfFalse [24] (0x120efd313ffa @ 36) ; jump? .end
Ldar r1 ; temp = a + b
Add r0, [1] ;
Star3 ;
Mov r1, r0 ; a = b
Mov r3, r1 ; b = temp
Ldar r2 ; i += 1
AddSmi [1], [2] ;
Star2 ;
JumpLoop [25], [0], [3] (0x120efd313fdd @ 7) ; jump .loop
; end:
Ldar r0 ; return a
Return ;
load_smi 0 ; a = 0
store r2 ;
load_smi 1 ; b = 1
store r3 ;
load_smi 0 ; i = 0
store r4 ;
; loop:
load r1 ; n0 = n # why isn't it directly using `n`?
store r5 ;
load r5 ;
cmp_lt r4 ; i < n
jump_if_false 32 ; jump? .end
jump 10 ; jump .body # numerical `for` should put the latch at end
# which would remove `jump.body` and `jump .loop` here
# the ending `jump .latch` would turn to `jump .loop`
; latch:
load_smi 1 ; i += 1
add r4 ;
store r4 ;
jump_loop 14 ; jump .loop
; body:
load r2 ; temp = a # probably same problem as `n0` above
store r6 ;
load r3 ; temp += b
add r6 ;
store r6 ;
load r3 ; a = b # need a `mov` that's a peephole of `load, store`
store r2 ;
load r6 ; b = temp # also mov
store r3 ;
jump_loop 26 ; jump .latch
load r2 ; return a
return ;
load_none ; return none # basic block DCE would eliminate this
return ;