#Nexirol&Renirol
2417 messages · Page 3 of 3 (latest)
Yup
... how is rider alone so much larger than intellij plus all the assorted plugins I have?
I mean over here it's not but like
why is the size so different in the above screenshot
ok the difference in the second one comes down to caches
speaking of which, I should probably clear caches to clean up some space on my laptop I guess
or at least I'm assuming it's caches
tomorrow, I'm setting up a readInt function for debug purposes
from there, I'm probably gonna setup arrays and make a snake game in my IR builder
Clangd + VSCode does a good job btw
(I do not do C/C++ dev stuff much)
also vscode just feels
off to me
I’ve done my best to configure it but it just never quite feels right for some reason
especially on windows
feels better to me on linux for some reason 
Based
^ this
I should prolly get clangd lsp running on nvim but thats for lame people
so in theory, my readInt function works
in practice, I haven't tested any of it yet (read text from console, nor string to int)
so we'll see how much of a headache that becomes, considering I didn't even refer to compiled C/C++; I literally just wrote the ir builder generation from experience
trying to write instructions after the end of a method creates a new block, thus crashing the compiler if the method is not a void and the block is unterminated, incredible
and trying to write my module to the disk segfaults the compiler, wha
Failed to acquire targetTriple: Unable to find target for this triple (no targets are registered)
oh
ah nice
readint segfaults the compiler 
actually read segfaults the compiler
wah
I'm stupid (I passed just the text as the argument instead of the list of arguments)
ok I now have like a bajillion validation errors but that's fine
in practice, int from string segfaults the compiler 
huh
my optimization pass set (which worked on int to string) segfaults it
Basic Block in function 'stringToInt' does not have terminator!
label %header
Failed to verify function stringToInt
yeah that explains it
and I think this is now my problem
... nope
okay I'm gonna have to refer to actual compilation results I think
declare dso_local %struct._iobuf* @__acrt_iob_func(i32) #2
define dso_local void @test() #0 !dbg !132 {
%6 = call %struct._iobuf* @__acrt_iob_func(i32 0), !dbg !140
%7 = getelementptr inbounds [100 x i8], [100 x i8]* %1, i32 0, i32 0, !dbg !140
%8 = call i8* @fgets(i8* %7, i32 100, %struct._iobuf* %6), !dbg !140```claude does not disappoint
took a four step back and forth to get here but 🤷
okay so there's a bug somewhere between reading the string and printing the integer version of the string
and I can eliminate the bug being in intToString, because that function is known to work
so it's either read string or stringToInt
I can narrow it down to stringToInt; printing the string repr works
okay qwhat
ah I was incorrectly allocating an extra string
makes sense tbh
eh that's close
yipee!
next:
- arrays so that I can represent strings
- snake game
if (!feof(stdin) && _kbhit()) {
fgets(chars, 100, stdin);
puts(chars);
}```where has this been my whole life 
(detecting if there's console input currently available)
declare dso_local i32 @_kbhit() local_unnamed_addr #3
declare dso_local i32 @feof(%struct._iobuf* nocapture) local_unnamed_addr #2
oh AND it's a direct translation to llvm ir, sweet
Im fine with with being pinged btw
nope, I still don't need msvc yet
reason: ucrt is an actual functional alternative to msvc for windows it seems
actually clangrt builtins alone is enough, huh
either that or these are working now
"/defaultlib:msvcrt /defaultlib:ucrt /subsystem:console /verbose"
oh they are
but yeah ucrt is enough
is lld-link redistributable?
or is there a different way I should do that? or what
Jai does it
incredible
O3-5 is aggressive enough that it can cause LLVM to segfault when validating the module 
or maybe it just doesn't like validating modules after optimization passes
lld-link: error: undefined symbol: __chkstk
but it also can't link
but msvc does solve that one
context: O3-5 basically tells llvm go do whatever the heck you want essentially 
I'm also sorta making a machine learning library for java in the background
using pytorch behind the scenes but I'm actually manually going through backpropagation, so I should be able to eventually switch to tensorrt or onnxruntime and still have the ability to train my models
error.ref();
Tensor scalar = value.compute().getEngine().create(DataType.FLOAT, 1);
scalar.set(value.compute().shape().size(axis), 0);
SymbolicTensor mulRes = error.div(scalar);
value.backward(mulRes);
mulRes.close();
scalar.close();
error.refLater();```manually as in manually telling my own api to tell pytorch to do it from within in my api
ok tensorrt might not be as viable for this 
onnx however maybe
library doesn't initialize properly, I need to do it manually using reflection, that's a new one
ya know what
maybe I should try out C# for my AI stuff
https://github.com/dotnet/TorchSharp
https://www.nuget.org/packages/MxNet.Sharp/1.5.1.7
regardless; work on compiler time
I just realized I "need" a random number generator 
👍 it does not work properly either
0 -> x+
1 -> y+
2 -> x-
3 -> y-
why I keep getting smiley faces, I do not know
llvm fails to optimize my snake game
I feel like I remember this 
block_1: ; preds = %head
br label %dir_out
block_2: ; preds = %head
br label %dir_out
block_3: ; preds = %head
br label %dir_out```~~I love llvm~~
like why even have those branches?
switch i32 %4, label %block_3 [
i32 0, label %dir_out
i32 1, label %block_1
i32 2, label %block_2
]
block_1: ; preds = %head
br label %dir_out
block_2: ; preds = %head
br label %dir_out
block_3: ; preds = %head
br label %dir_out
dir_out: ; preds = %head, %block_3, %block_2, %block_1
%var66.0 = phi i32 [ 0, %block_3 ], [ -1, %block_2 ], [ 0, %block_1 ], [ 1, %head ]
%var67.0 = phi i32 [ -1, %block_3 ], [ 0, %block_2 ], [ 1, %block_1 ], [ %4, %head ]
oh maybe I understand
why does it jump back and then go forward 
and also why does it skip a row 
That’s how snakes go 🐍
oh because I'm using size2 and summing one
instead of size and sum 2
nvm

oh actually I prevented myself from compiling because the program was open 
buh
answer: my board was messed up
had my new lines being filled in at the wrong offsets
that's a lot easier to see what's wrong
ey
the TODO:
- make tail not segfault game
- apple
- make snake grow
- make game loop not wait on input but instead happen at an interval
snek
writing this takes SO MUCH MORE THOUGHT
than the TI84 calculator equivalent holy heck
very hard to remember what number does what
isLoss = function.compare(CompareOp.EQ,
function.compare(CompareOp.EQ, isLoss, CONST_1),
fTurn.get()
);```me when I don't have boolean math
great, but there's a random tile that kills the player when the player goes over it
this single specific tile for no apparent reason
oh there's more than that
oh
my first turn logic also isn't working, given the fact that I never set it to not the first turn
ok boolean op time
... and there's still random tiles that kill me :yipee:
I think it's just two specific ones even
forgetting to reset loop indices moment

and I got my controls mixed up 
glad I can at least use RLX level 4 optimization 🤷
(RLX L4 is, a decent bit of optimization, not quite as aggressive as O3, but it's meant as an assistant optimizer sorta thing)
gets logic of abs perfectly implement first try, except it always returns a negative instead of a positive
so you wrote the programming language you used to make this game?
VarInstr i0 = function.makeVar(RlxTypes.INT);
ValueInstr CONST_0 = new ConstInstr<>(0, RlxTypes.INT);
ValueInstr diff = function.sub(right, left);
RlxBlock blockL = function.makeBlock("block_l");
RlxBlock blockR = function.makeBlock("block_r");
RlxBlock blockD = function.makeBlock("block_d");
ValueInstr cmp = function.compare(CompareOp.GE, diff, CONST_0);
function.jumpIf(cmp, blockL, blockR);
i0.set(diff);
function.jump(blockD);
function.buildBlock(blockL);
i0.set(function.sub(CONST_0, diff));
function.jump(blockD);
return i0.get();```
well it's not a lang yet; I'm trying to make sure rlxir is in a viable state for things
but yeah
pretty impressive
https://github.com/GiantLuigi4/ralux/tree/master/rlxir/src/main/java/tfc/rlxir
it's a simplified abstraction over LLVM so that I don't have to do as much tracking and can focus more on just having things work™️
still pretty close but it just deals with more stuff for me than llvm does by default
huh that's-
interesting
not sure what just happened there 
smth smth recompiled program while closing ig, idk
it is a lot more effort to write snake this way than it would be in an actual lang 
I bet
buffer overflow attack performed!
180x180
my screen is not tall enough
it took many moves to get down here
I made 1 missinput, and said input was discarded because it was invalid
only thing remaining is abble
and also validating when the player moves out of bounds
https://github.com/GiantLuigi4/TScript/blob/master/src/Examples/SnakeGame.tscr
I have no memory of how to write this stuff
so glad rlxir is not like that
:car: you cannot make a 102864x102864 board
715 is the limit
511225
yeah that makes sense ig
actually no it doesn't, what
514088```
that's just an arbitrary value that doesn't even seem to correlate to anything-
huh?????
whatever
I'mma just do apple, I don't really care about bounds checking
let's see what claude has to say about rng
... not sure if what it said is real 
I'mma just make the call to capi
I'mma guess it's due to stack space or smth
according to claude, I am probably correct
declare dso_local i32 @rand() #1
another nice&simple function
although C's random impl is a huge disappointment to me, so another one for the debug purposes pile
(I just don't like how I have to go out of my way to seed it compared to just using it normally, would rather have to go out of my way to use it in the first place so that seeding is the same amount of out of my way)
(also I like control and I feel like I don't have that with C's impl
)
oh what a joke
(may be my fault but it's always returning 5 for bounds 0->5)
ok it's just C's impl being shoddy
start of apple
I don't even want to image programming pong like this 
that seems like a nightmare
snake's nice and simple
Yup
I started with a snake game
Pong has a little vector math in it, just some dot product for the bounce and multiplying a vector
Otherwise similar
which is a significant amount when you're dealing with this low level of a syntax 
Yeah I bet
Also have to normalize I forgot
I may not be able to eat the apple, but I sure can eat the line breaks 
ignore that todo, I just hadn't gotten around to removing it
remaining ir features:
- calls
!operator- short circuit builder
remaining backend features: - linkage
- xor, nor
remaining frontend features: - everything between ast and rlxir

somewhere in there a gc is needed
which...
I will probably have as just a required package sorta thing
Probably written in none other than ralux
And impls for any broken intrinsics I run into 
My favorite thing about the jvm
is that there is a solution within the jvm to absolutely every problem the jvm creates
awt is poorly optimized?
you can reimplement it yourself
but wait there’s a problem — java 9 modules get in the way
but there’s most assuredly a way to bypass the entirety of the jvm’s security nonsense to optimize it anyway 
it’s fun doing these ridiculously over engineered things to get around jvm limitations
Kotlins only problem is the fact it runs on jvm :(
Kotlin is a great language
super fun to build with
I wrote a little maze solver in it once nearly 10 years ago https://github.com/btipling/maze-solver
Aside from JNI
What’s wrong with the JVM :iea:
Especially modern versions of the JVM
Nothing, just kotlin could’ve improved a few things if they rolled their own java bytecode compatible vm, although I havent used either in a while so things might be a lot better now
I feel like a custom jvm is not going to fix bytecode which validates everything between every line 
you do not need to nullcheck an object every time it gets referenced, which iirc, is something kotlin’s compiler generates 
but openjdk’s been getting more and more jit optimizations added to it, and things are getting deprecated pretty rapidly (which is good)
👍
Granted, I also have not looked at kotlin in a while
so maybe the compiler has changed
Unless you’re doing something oddly specific, the JVM is usually not the bottle neck/limiting factor
SIMD is the main thing that the JVM doesn’t support afaik
Tragic
Also
Dear LORD WHAT THE HECK IS SCALA’S BYTECODE OUTPUT 
working with a scala library drove me insane 
How scuffed does your bytecode need to be to get an IDE to generate this 
Whatever the heck scala is doing
The jvm was NOT the right choice 
fairly clean
probably would be cleaner if I wasn't using antlr but like
meh
I don’t really wanna handroll a parser
return ((left < right) * (right - left)) + left;
kinda tempted to setup the compiler to optimize stuff like this
%zext_int1_to_int32 = zext i1 %si_cmp to i32
%si_product = mul i32 %zext_int1_to_int32, %si_diff```ig basically just if detect cast bool->int followed by mul, convert to branch
ok so I managed to eliminate all symbol not found problems except for __fixtfsi it seems
ig I'll just have to manually implement specifically that one
pkg comptest;
use ralux.debug.Debug;
public class IOViaDebug {
public static int main() {
Debug.write(5);
long lng = Debug.readInt64();
Debug.write(lng);
return 0;
}
}```but I can compile stuff like this class!
which, does not do much, but it's good progress
next comes writing a horrible garbage collector implementation in C++ 
(I can't really, do much in the way of the standard library without arrays, and I kinda need some kinda basic garbage collection for arrays just so this way I don't have to rewrite like half the compiler later on)
So __fixtfsi is for float128 to int32
and it seems like none of the __fixtf** functions exist
So I guess those were just not implemented into any of the runtime libraries for some reason?
Haven’t run into any other broken intrinsics than those after linking to all of
- msvcrt
- ucrt
- libcmt
- compilerrt builtins
at once
You werent linking them at once????!!!??!!
I was but I guess I must’ve been missing one
But thats kinda funny windows requires so much overhead to be linked with c std lib
yeah
Guess I’ll just have to include intrinsics for tf->** conversions in my own lib
‘Cuz wides and quadruples are syntax features of ralux
The only reason to link with the c std lib is for easy os calls, of course implementing your own std lib is extremely hard which is why a lot of compilers dont do it
rlxrt is mostly gonna be like
gc and whatever broken intrinsics I encounter
Fortunately I can use strip unused symbols to get rid of a lot of that 
Yeah, still requires a slightly noticeable amount of time to strip though (atleast from what Ive seen with other compilers)
I’m honestly considering making my own linker ‘cuz like
this is a bit ridiculous 
Mold is good
Mold is fast
Lld is also plenty good
I’m honestly not actually sure what version of lld I’m using
Jeeze
1.5 seconds to link chromium 
that is insane 
It takes 53 minutes to build cryengine
oo mit too
Might actually use mold then
oh, kernel32 as well
lld-link: error: undefined symbol: __std_exception_destroy
though msvc strikes again!
linking against my own runtime library doesn't work because msvc seems to be using symbols that are not included in msvcrt
solution: cstdlib
incredible
"/libpath:\"C:/Program Files/LLVM-13.0.1/lib/clang/13.0.1/lib/windows\" " +
"/defaultlib:msvcrt " +
"/defaultlib:libcmt " +
"/defaultlib:ucrt " +
"/defaultlib:cstdlib " +
"/defaultlib:kernel32 " +```what it takes to compile a program in windows
aw, no windows builds
oh nvm cstdlib doesn't exist
so apparently
my library is using vcruntime
which causes lld to also generate a lib file in addition to the exe
... what the heck
oh halves don't even exist in C/C++, incredible
okay probably going to have to write my intrinsics in something even lower level then
declare void* @tfc_ralux_runtime_GC_allocate(void* %0, i32 %1) declare void* @tfc_ralux_runtime_GC_collect(void* %0, i32 %1) declare void @__rlxrt_init() declare void* @__rlxrt_get_global_gc() declare void @__rlxrt_obj_created(void* %0) declare void @__rlxrt_free_obj(void* %0)```
ok so order of operations:
hook up gc->implement object orientation->test gc->instance functions->fields->compiler hints->standard library->remaining syntax features
after writing some of the world's most cursed C++ code...
and it segfaulted after printing that 0
int hc = o.#;
was supposed to get the hash code so I think I know why it segfaulted
my gep is wrong
puts("allocate obj");
puts(std::to_string(size).c_str());
puts(std::to_string(sizeof(rlxObj)).c_str());
void* data = tfc_ralux_runtime_GC_allocate(gc, size + sizeof(rlxObj));
void** obj = static_cast<void**>(calloc(1, sizeof(void*)));
obj[0] = data;
puts("buf_alloc'd");
((RlxObj) obj)->tfc_ralux_runtime_Object_hashCode = __rlxrt_default_hash;
puts("hash_code_set");
__rlxrt_obj_created((RlxObj) obj, gc);
puts("obj_marked");
return obj;```^ to define "some of the world's most cursed C++ code"
so an object is actually a void** in C++
interesting, I can abuse that
explains why geps go two steps instead of one too
%call7 = call i8* @tfc_ralux_runtime_GC_allocate(%"struct.ralux::rlxGC"* poison, i32 noundef %add)
%call8 = call noalias dereferenceable_or_null(8) i8* @calloc(i64 noundef 1, i64 noundef 8)
%2 = bitcast i8* %call8 to i8**
store i8* %call7, i8** %2, align 8
%call9 = call i32 @puts(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @"??_C@_0M@JPCHMAAE@buf_alloc?8d?$AA@", i64 0, i64 0))
%3 = bitcast i8* %call8 to i8***
%4 = load i8**, i8*** %3, align 8
%arrayidx11 = getelementptr inbounds i8*, i8** %4, i64 2
store i8* bitcast (i32 (%"struct.ralux::rlxObj"*)* @__rlxrt_default_hash to i8*), i8** %arrayidx11, align 8```lovely (I have no idea what the heck I'm looking at but I need to figure it out so I can reproduce it over in the ralux compiler)
oh right I'm using pointers to all objects
still. I can abuse it
I can store ref counting and gc related data in the first pointer instead of having that be part of the object
which is the sorta thing C++ would do (it seems)
or smth idk I still need to figure out why my code segfaults the compiler
((int (*)(void**)) ((void**) ptr[0])[2])(ptr);
```ok so this is the C++ equivalent of what I want
%0 = load %"struct.ralux::rlxGC"*, %"struct.ralux::rlxGC"** @"?tfc_ralux_runtime_GC_GLOBAL_GC@ralux@@3PEAUrlxGC@1@EA", align 8, !dbg !4198, !tbaa !3907
%call = tail call i8** @tfc_ralux_runtime_GC_allocateObj(%"struct.ralux::rlxGC"* noundef %0, i32 noundef 0), !dbg !4198
call void @llvm.dbg.value(metadata i8** %call, metadata !4197, metadata !DIExpression()), !dbg !4199
%1 = bitcast i8** %call to i8***, !dbg !4200
%2 = load i8**, i8*** %1, align 8, !dbg !4200, !tbaa !3907
%arrayidx1 = getelementptr inbounds i8*, i8** %2, i64 2, !dbg !4200
%3 = bitcast i8** %arrayidx1 to i32 (i8**)**, !dbg !4200
%4 = load i32 (i8**)*, i32 (i8**)** %3, align 8, !dbg !4200, !tbaa !3907
%call2 = tail call noundef i32 %4(i8** noundef %call) #18, !dbg !4200
ret void, !dbg !4201```which compiles to this
which is subpar but currently I just want stuff to work
Or maybe it’s not subpar
Hard to tell
%1 = cast void** to i8***
%2 = load i8** from %1
%3 = gep i8* from %2 at 2
%4 = cast %3 to fnct
%5 = call %4
Ideally I’d have typedefs for each class
But I can’t really be bothered to set that up until I know stuff works and I know how I wanna structure stuff
So
I think plan is
[[fields&method refs], rlxClass*, rlxGCInfo*, interfaceExtensions*…]
super calls just call a static function which is the super method (as per standard language logic)
When casting to an interface, lookup in the class instance what said interface’s offset is
When casting back to the object, interface extension instance stores its own offset so just subtract that from the pointer
This also seems to be, to an extent, how C++ handles stuff, but not entirely
C++ implements super classes as a field, which definitely makes sense for a library but for an exported program it’s unnecessary
But I’ll probably want an interop mode I guess because my way seems, probably better for performance while C++’s seems better for native libraries
Though I should probably also look into dlls a bit more before deciding on how I wanna deal with libraries tbh
so apparently having my ide open and set for working on ralux makes my ide use up 40% of my RAM
I only have 20% RAM free at any given moment without my IDE open
working on ralux brings my laptop use 120% RAM
I can tell it worked because the program closes essentially instantly after starting 
yep
I think the first thing I’ll try to make with ralux is a graphing calculator
So after attempting to use a loop
C++ has decided it wants to be so extremely riddled with undefined behavior that it’s somehow calling ref from ref from rt init
only function rt init calls is init gc, which doesn’t even call ref
… so I’m not sure how it’s getting to ref
I have no idea what’s going on
At least whatever’s happening happens both with and without gdb unlike what I had before where it would randomly segfault but ONLY if I don’t attach gdb
probably gonna have to rewrite the gc entirely because what the heck

none of this makes sense 
ok so apparently libucrt causes everything to have a stroke I guess
oh hey
it's exactly the thing I don't like about C++
things seem to just get freed for no apparent reason sometimes
C++ stack memory my enemy
or smth
idk
@lapis turtle https://github.com/GiantLuigi4/ralux/blob/master/RlxRuntime/RlxRt.cpp
this is bad code and I’m aware of that fact but like
how do I even begin to debug this sorta thing
it works if I attach a debugger, elsewise it behaves stupidly and I don’t know why
I’ve tried making the code more cursed, I’ve tried making it less cursed, nothing seems to change the behavior
closest I got to a behavior change was making the program not load at all
every time I deal with C++ I seem to end up with stuff just arbitrarily being freed
RAII
Things destructors are called when they go out of scope
And… how do I prevent that?
Making the things not go out of scope
And stack variables are invalidated when out of scope as well
… is malloc not off stack?
Yes
Raii deals with classes though
It deals with your constructor and desctructor
What is raii
Mind pointing me to an example of wherever this is a problem?
new keyword?
new isn't a preferred method but it can work
I don’t know where I even have a stack object other than my unordered sets
RAII doesn't deal with stack
stack variables are invalidated purely because of how the CPU works, RAII is a memory management concept introduced by c++
{
type thing{}; // constructor allocates memory
} // destructor is called
cppref has a good thing on RAII
I don’t
use constructors or destructors
theres default implicit ones
other than with the new keyword
Ok but why th is it being destroyed then
it goes out of scope
^
the default destructor is called, deallocating your memory
ok but it was allocated using new, not using the default initialization
RlxObj is a pointer type to rlxObj
^
might be worth to talk to someone who is more of a cpp person, they'd prolly explain this better
ok then how do I prevent it from being deleted when going out of scope because it’s only going into a field and not meaningful in scope
put it in a higher scope
That would be the thing that I don’t want it to be in the scope of because this is so that that doesn’t have to deal with it
… so I guess you’re getting at me needing to make my own allocator in that case?
one which I really wish didn’t exist
you prolly dont need to use the new keyword on a lot of stuff
stack allocation is always preferred
the new keyword in c++ is extremely different than in java
every class has raii
new in c++ allocates memory using the constructor whereas in java the new keyword is just calling the constructor
ok so malloc will avoid this?
again
no
if you have a pointer to a class it will free it at the end of scope
oh
so it needs to remain as a void** the entire time
{
classtypething *thing = new classtypething; // allocated here
} // freed here
im not sure what the behavior is here, as again im not a very oop-minded or even c++ minded programmer but I assume this will not change the behavior
^
yeah this wont change anything after a quick search
just will free for you
this is likely a project structure issue
either that or its not that things are being freed and you have heap corruption
incredible
maybe dont try to make a program where everything is local scope :p
… not what I meant
I’m trying to recreate how java object orientation works
but C++ aggressively wants to delete everything that is allocated in a scope
which is, distinctly the dead opposite of what I want
given the fact that I have a library which has the sole purpose of managing allocations and garbage collection
then use java
c++ oop is different for a reason, c++ is not like java, java is not like c++
and then I have to deal with jni and not have simd and whatnot
which is, also not what I want to do
I’m not even trying to use C++ really
I’m trying to just get a thing going to act as a garbage collector because doing in llvm ir would be painful
I would do this in C if C had unordered_set, but unfortunately it does not
But maybe I need to
yeah I’m not really interested in fully learning C++ just to then move off of C++ after my language is more developed or something
this is most likely going to be a temporary throwaway codebase for testing stuff
you also dont have to use c++ either, c doesn't have RAII
C lacks unordered set
I don’t know how hashmaps work behind the scenes
you dont have to with a premade one
but also you definitely should
learn it
its an extremely useful pattern
Particularly I don’t understand what the heck to do if the bucket count needs to change or does it ever change or what
realloc
anyways
like I've stated im not the best person to console about c++ issues, as I myself, am not a c++ programmer
Would…
That not cause hash alignments to mismatch?
I mean
Hashmap isn’t C++ stuff
your issue is either heap corruption or incorrect raii
No?
Which
knowing about raii makes me want to just abandon C++ so that I don’t have to deal with that and use C instead, as I’ve stated
Join the cult
… how?
bucket index (based on my last time googling how hash maps work) is hashCode%bucketCount, which if bucket count increases by 1, a hashcode that might’ve modulated to 1 might now be 2 or smth?
theres a lot of ways to do a hashmap, so may be true in some cases
raii’s getting in the way and I don’t think I have any way around it
Previously I thought this was something about c++’s string class but I guess it’s just C++ in general 
I just want to manage my memory fully manually 
I think you’re just having a logical error, have you also not booted uo the vs debugger?
don't know how to use VS debugger with a lib file that's compiled with clang through command line
also yeah I am infact having a logical error
void* data = tfc_ralux_runtime_GC_allocate(gc, size + sizeof(rlxObj));
void** obj = static_cast<void**>(calloc(1, sizeof(void*))); // this is the cause of my problems
obj[0] = data;```
annoying that it ever works instead of just always failing
I'm sticking with C though
void* obj = tfc_ralux_runtime_GC_allocate(gc, size + sizeof(rlxObj));
```should've been this
Nice
I'm going to use a linked array set for now
because it's the simplest type of set to implement
and I'll rewrite it to a hash set later
er
no I'll go with regular arr-
oh I could d-
eh-
yeah binary tree map based on memory address seems good enough for now
eh no I'll just go linked list
✨ indecision ✨
array set
ok so stuff is working, but running the gc breaks the gc 
like it works, until the gc runs a second time
reason: the objects that are freed don't get removed from being roots... I think
which is my fault; I never implemented that
but i think I need to test my array set's remove method outside of ralux so that I don't have an absolute mess every time I try to test it
well not removed from being roots; it's already not a root elsewise it wouldn't be freed
removed from being tracked by the gc
pkg comptest;
use ralux.debug.Debug;
use tfc.ralux.runtime.GC;
public class ObjectOrientation {
public static int main() {
for (int i = 0; i < 32000; i++) {
ObjectOrientation o0 = new ObjectOrientation();
ObjectOrientation o1 = new ObjectOrientation();
int hc = o0.#;
Debug.write(hc);
Debug.write(i);
o0 = null;
o1 = null;
}
GC gc = GC.getGlobalGC();
GC.collect(gc);
Debug.write(100);
return 0;
}
}
``` array set works properly
yeah onto the next problem now 
what.

nice, roots work too
8KB binary, RlxRt.lib is 18KB
not entirely sure how that works but 
(rlxrt can be shrunken down to 7kb dependent upon llvm switches)
3200000
1652646
1547354```
program runs pretty fast too
halfway through 3200000 iterations
28????? at this point
not timing this obviously but like
yeah that's a decent speed
just finished
I'd imagine it'd be faster if I had a heap and also used a hash set
the array set was infact atrociously slow, so I implemented a binary search based array set
this will stay for now 🤷
will need to be redone later though
okay so it looks like I'm not freeing everything
wait that's probably the array sets, lol
yeah looks to be a reasonable size for being the array sets I'm using to track objects
shoot I need to update my parser to support fields
I think fields are the last thing before ralux is usable
Eh I need to do arrays at some point too
I can now get values from fields
only problem
I can't set values in fields
should be simple enough to implement though 🤷
5368713536
10
20
10
30
5368713536
22
10
track root
obj addr: 5836320
Marking object
489324
Marking object
track indrect root
obj addr: 5836416
Marking object
489324
Marking object
An obj was freed
An obj was freed
reference tracking works
made my binary search array set impl be a single header library so that LLVM could go completely insane with inlining
the IR is now completely incomprehensible
it happens in C too it seems