ChanServ changed the topic of #zig to: zig programming language | | be excellent to each other | channel logs:
marijnfs_ has quit [Ping timeout: 246 seconds]
marijnfs_ has joined #zig
Ichorio_ has joined #zig
Ichorio has quit [Ping timeout: 264 seconds]
muffindrake has quit [Ping timeout: 246 seconds]
gruebite has quit [Quit: WeeChat 2.6]
muffindrake has joined #zig
voldyman has joined #zig
waleee-cl has quit [Quit: Connection closed for inactivity]
keithdc has quit [Quit: leaving]
Jezza__ has joined #zig
traviss has quit [Quit: Leaving]
muffindrake has quit [Ping timeout: 264 seconds]
Ichorio has joined #zig
muffindrake has joined #zig
Ichorio_ has quit [Ping timeout: 264 seconds]
Jezza__ has quit [Ping timeout: 250 seconds]
chemist69 has quit [Ping timeout: 245 seconds]
chemist69 has joined #zig
mahmudov has quit [Ping timeout: 240 seconds]
chemist69 has quit [Ping timeout: 245 seconds]
chemist69 has joined #zig
voldyman has quit [Quit: Connection closed for inactivity]
ky0ko_ has joined #zig
ky0ko has quit [Disconnected by services]
ky0ko_ is now known as ky0ko
ky1ko has joined #zig
<ky0ko> is it possible to get the size of an extern struct in zig? i'm working with (and porting) c code and i am trying to memset a struct to 0.
<mq32> @sizeOf(StructType)
<ky0ko> @sizeOf just gives me an error because it expected type 'type' and not '.cimport:2:11.server_t'
<mq32> @sizeOf(@typeOf(your_server_var))
<ky0ko> that worked, thanks
<mq32> you'r welcome!
Ichorio has quit [Ping timeout: 250 seconds]
<nrdmn> where's builtin.os defined?
<nrdmn> hmm, I think I've found it
knebulae has quit [Read error: Connection reset by peer]
<mq32> oh man. programming in zig is just a pleasant experience :)
<mq32> aaand another bug
knebulae has joined #zig
jjido has joined #zig
<gonz_> Quick check; there weren't a bunch of join/part/quit messages from my client recently, right?
<gonz_> I've been fiddling around with using IRCCloud as a bouncer
<gonz_> is why I ask
<gonz_> I don't want it spamming when I open/close the client
<mq32> nope, seems fine
lucus16 has quit [Quit: No Ping reply in 180 seconds.]
<gonz_> Great
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
FireFox317 has joined #zig
jjido has joined #zig
FireFox317_ has joined #zig
Ichorio has joined #zig
<FireFox317_> for the OS people in here, an other good resource might be SerenityOS by Andreas Kling ( It's a really well written kernel and userland libraries.
<mq32> wow this looks cool
dingenskirchen has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<gonz_> #serenityos for people interested in it as well
<gonz_> The IRC channel is the main community spot, so it's not just a dead appendix hanging on for dear life
jmiven has quit [Quit: bye]
jmiven has joined #zig
keithdc has joined #zig
jjido has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jjido has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
waleee-cl has joined #zig
<mq32> hey
<mq32> can someone help me a bit with inline assembly/x86?
<mq32> pixelherodev probably?
<nrdmn> mq32: what can we help you with exactly?
<mq32> i want to implement outb, outw, inb, inw
jjido has joined #zig
<mq32> current attempt looks like this:
<nrdmn> I think in the first parameter you have to put aliases in %[], like "outw %[port], %[data]"
<FireFox317_> mq32: This might help a lot,
<FireFox317_> We use the same syntax I'm pretty sure
<nrdmn> FireFox317_: clang only implements a subset of gcc's syntax
<mq32> hm, now it doesn't compile anymore ^^
<mq32> ah damn.
<mq32> solution was, that explicit register names require {}
<mq32> otherwise, it gets handled ... differently
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<mq32> can someone tell me if this is the right way to "read" a register into variable?
<mq32> _start gets called with with eax and ebx filled and i want to read them into certain values
<mq32> ah damn. looks like this isn't possible in pure zig and debug mode
saskwach has joined #zig
<mq32> can i export a symbol from inline assembler?
<nrdmn> what do you mean by that?
lunamn_ has joined #zig
lunamn has quit [Ping timeout: 240 seconds]
<mq32> i need some pure assembler function
<mq32> but i don't want to create a new assembler file for 4 lines of asm
<mq32> so i want to export a symbol/label from the inline assembler
jjido has joined #zig
LLIypuk has joined #zig
LLIypuk has left #zig [#zig]
<saskwach> I'm a little confused by the `if` syntax in Zig. Are `if (foo) |bar| { ... }` and `if (foo) { ... }` fundamentally different? It seems like the first one unwraps errors and executes the block regardless of value, while the second one only executes if bar's value is true. Is that right?
<saskwach> (executes the block)
<waleee-cl> saskwach: errors AND optionals
<saskwach> Ok, so `if (a) |b|` has nothing to do with boolean values?
<waleee-cl> from my relatively new experience, no, not in that form.
<saskwach> okers
<saskwach> Seems like an odd choice.
<waleee-cl> well, otherwise you'd have to do a bit more ceremony for null-checking &c
<saskwach> Or just use a different keyword. `unwrap (a) |b| { ... } or |c| { ... }` is a little longer, I guess, and adds a keyword to the language.
<waleee-cl> I guess you have seen some longish unwrap-chains in rust?
<saskwach> Maybe a bit.
<saskwach> Though Rust seems to be all about the chains.
<saskwach> I do really like just passing types around as values though. And it's refreshing to see something like D's scope statements again.
<nrdmn> waleee-cl: rust has `if let Some(b) = a { ... }`
FireFox317_ has quit [Ping timeout: 240 seconds]
FireFox317 has quit [Ping timeout: 240 seconds]
<waleee-cl> yeah, I have seen that one. Not terrible fond of it since it allows for unwrapping of any type
<waleee-cl> (which can be a good thing)
<saskwach> I find that weird in Rust. It makes me want to pattern match unwrap things in other contexts, but I can't.
<pixelherodev> mq32, still need help?
<mq32> yeah
<mq32> struggling with exporting that symbol
<mq32> and i can't use nakedcc as it will clobber eax,ebx in debug mode
<pixelherodev> For Zig interfaces to I/O right?
<pixelherodev> I *think* i have a better solution for you
<mq32> ah no
<mq32> for multiboot-to-os-entrypoint
<mq32> but tell your idea
<pixelherodev> Ah, you got the inline asm working then?
<mq32> yes :)
<mq32> i have output on the serial console
<pixelherodev> Alright cool :)
<mq32> yeah
<pixelherodev> My multiboot stuff is all in Zig, no asm
<mq32> okay, how did you solve the passing of parameters?
<pixelherodev> (Except to read %ebx for info)
<pixelherodev> s/info/address
<pixelherodev> From what to what?
<mq32> err
<mq32> how does your parse() function return the value?
<pixelherodev> It gets it straight from %ebx
<pixelherodev> That contains the address
<mq32> okay, but ebx gets clobbered
<pixelherodev> When?
<pixelherodev> The fact that I'm using that address indicates otherwise :)
<pixelherodev> I'd say it's more accurate to say it *could* get clobbered, which is a different problem
<pixelherodev> My solution is moving multiboot.parse() into start before the newStackCall to kmain, the using multiboot.get() in kmain
<pixelherodev> Haven't pushed that yet
<pixelherodev> ...can usingnamespace be using on a pointer-to-struct?
<andrewrk> it takes a type
<pixelherodev> So it only works on *constants* then, right
<pixelherodev> Makes sense
<andrewrk> types are always comptime known
<pixelherodev> Was trying to think of a way to remove the need for .get()
<pixelherodev> Without copying the memory pointed to by the multiboot header
<pixelherodev> Oh wait, I got it :)
<pixelherodev> Going to leave multiboot.zig alone and just pass the pointer from start to kmain
<mq32> pixelherodev:
<mq32> andrewrk, do you know how to export a symbol from inline assembler
<andrewrk> .symbol
<pixelherodev> mq32, I'd switch that a bit
<andrewrk> oops that's the section. `.globl symbol_name_here`
<pixelherodev> Make it two inline asms which return the value
<mq32> pixelherodev, yeah but this won't solve my problem ;)
<mq32> andrewrk, thanks, gonna try i
<pixelherodev> Why do you need to export from inline asm? What's being exported?
<mq32> just _start
<mq32> because i need to save eax, ebx before calling into any zig code
<pixelherodev> No you don't :)
<pixelherodev> You can write start in Zig
<pixelherodev> Try using `var magic = asm("" : [] "={eax}" (->u32));`
<pixelherodev> Still getting clobbered?
<mq32> ah no
<mq32> doesn't seem so
<pixelherodev> :)
<pixelherodev> (though of course I forgot that a symbol is required for the label :()
<pixelherodev> Ah, there's a problem with that too
<pixelherodev> It puts it on the stack
<pixelherodev> Minor optimization note: when calling a noreturn function with newStackCall, it still generates instructions after call
<pixelherodev> (restoring the stack)
<pixelherodev> More relevant optimization note @mq32 that `const magic` (I set it to const in mine since it's never changed :) generates "movl%eax, -4(%ebp) \ movl -4(%ebp), %ecx`
<pixelherodev> Instead of moving it straight to ecx, it uses the stack first
<pixelherodev> Even though it's literally never used for anything other than moving to ecx (which is the parameter used for the function call).
<pixelherodev> As such, it's undefined behavior.
<pixelherodev> Also gives the wrong value :(
<pixelherodev> Hmm, what about pushing it straight to the stack slice? :P
<pixelherodev> If there was @newStack with calling, this would be much easier :P
FireFox317 has joined #zig
FireFox317_ has joined #zig
mahmudov has joined #zig
<pixelherodev> Got it working :)
<mq32> pixelherodev, got it working here. i don't use local variables for the multiboot stuff
<pixelherodev> Neither am I anymore
<pixelherodev> Though I am using an @inlineCall to multiboot.parse instead of doing it manually
<pixelherodev> There is a bug I noticed though, and not with my code, with the Zig compiler: we *can't* generate `movl%edx, -4(%ebp)` in start, but it does so as part of newStackCall
<pixelherodev> It moves the old stack into ebp, the new stack in place, then pushes the old stack to -4(ebp)
<pixelherodev> ebp isn't set by the entry point, which means it's *undefined*
<andrewrk> pixelherodev, it might not be possible to do @newStackCall soundly with llvm
<pixelherodev> The real problem then is is that practically speaking, ebp is zero at start for me
<pixelherodev> Which means `ebp - f` is potentially writing to e.g. MMIO at the top of the address space
<pixelherodev> andrewrk, that makes sense, but is also concerning
<pixelherodev> Is there no operation for "load stack" without saving the old stack?
<pixelherodev> @newStackCall as it is makes perfect sense on all non-freestanding targets
<pixelherodev> And even on freestanding, it's only problematic within the entry point
<andrewrk> arguably this is a bug in llvm since we're using
<pixelherodev> Not really
<pixelherodev> ""The ‘llvm.stacksave’ intrinsic is used to remember the current state of the function stack"
<pixelherodev> That's exactly the problem
<pixelherodev> We shouldn't use that in the entry point on freestanding
<pixelherodev> Better yet: that gets back to my optimization note from before
<andrewrk> oh I see what you're saying
<pixelherodev> When calling a function marked `noreturn`, we shouldn't use that
<andrewrk> that's a good point, and should be easy to implement
<pixelherodev> I'll see if I can implement this one myself
<andrewrk> codegen.cpp:4212
<andrewrk> you can look at src_return_type->id == ZigTypeIdUnreachable
<pixelherodev> Wow yeah that is easy
<pixelherodev> Just need to test it
<pixelherodev> GitHub PR the preferred method of sending in patches for ziglang?
<andrewrk> yes please
<andrewrk> mikdusan, I wonder if ConstGlobalRefs is the culprit in #3502
<andrewrk> either that or ConstParent
<andrewrk> these are used to identify that a value is an array element or a struct field of a parent value
<andrewrk> so if you interned one of them, that would potentially move it to the wrong parent
<andrewrk> unless the ConstParent data is out-of-band of the interned value
<mikdusan> ah i'll take a look at that
<andrewrk> this would explain why it works for type-has-one-possible-value, because such types have 0 bytes at runtime, and so can't really have meaningful parent values
<andrewrk> this ConstParent thing is necessary for comptime pointer reinterpreting
<andrewrk> ConstGlobalRefs is more of an implementation detail of code-generating constants
<pixelherodev> Found another optimization issue: there's an explicit `andl $15, %edx` generated for all align(16) objects, which shouldn't be there
<pixelherodev> (that's an example, but it's true of all align() types)
<pixelherodev> It's explicitly set to 16-byte alignment in the assembler anyways, so it accomplishes nothing
<pixelherodev> (just going over the produced asm manually and I noticed this, not touching this now)
<pixelherodev> There's about three extra instructions whenever an aligned pointer is used AFAICT
<pixelherodev> Plus it requires usage of another register, which is both unnecessary (it could just use andl 0xFFFFFF00 on the original instead of using andl 0xFF on a copy and subtracting the copy) and potentially damaging in a function that already requires a lot of registers
<pixelherodev> Yeah, asm looks good to me
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<saskwach> Is there a way to get a method namespaced inside a struct that doesn't take an instance as its first parameter?
<saskwach> (see also: static methods)
<saskwach> Oh wait, is it just "don't call the first argument self?"
<saskwach> Or am I being dumb and there's no implicit passing of the first argument?
<pixelherodev> calling an object of a struct type implicitly pass that parameter
<pixelherodev> For static methods, leave out that first parameter, and call it on the base type
<pixelherodev> e.g. if you have `const a = struct...;const b = a{}...`, do `a.method();`, not `b.method();`
<fengb> It’s really simple: all functions can be invoked statically or methodly. But static functions would throw a type error
<saskwach> Is that enforced by the compiler? I guess the first argument's type would have to be the struct for it to get confused.
<pixelherodev> I've done stuff like use `struct { fn func()void {}}.func();`
<saskwach> Yeah, that makes sense.
<pixelherodev> (though of course that's just a reduced example)
<pixelherodev> saskwach, what you name the first argument has zero effect on anything outside the function's scope
<fengb> It’s typechecked yes
<pixelherodev> All it does is give the parameter a label within the function itself
<pixelherodev> Compiler doesn't give a crap what you call it, self is just the label used by convention
<saskwach> So are structs the default mechanism for namespacing?
<andrewrk> yes
<pixelherodev> And since @import returns a struct...
<saskwach> Well that's simple enough.
<pixelherodev> I'm going to work on patching the stdlib for custom OS values now :)
<pixelherodev> (PR opened for newStackCall fix, lucky number is 3535)
<andrewrk> thanks!
<pixelherodev> No problem!
<pixelherodev> Just need to clean up my repo first (commit existing changes) and then I can get to work
FireFox317_ has quit [Ping timeout: 268 seconds]
FireFox317 has quit [Ping timeout: 268 seconds]
<pixelherodev> Might want to hold off on that patch for a bit, need to double check something
<pixelherodev> ...never mind, I'm an idiot.
<pixelherodev> I removed the -sse from codegen.cpp so it wouldn't show up in the patch
<pixelherodev> I forgot to put it back :P
<pixelherodev> ...oh wait, I think should submit a PR for this too :)
<pixelherodev> Yeah, 3535 is fine, but without 3636 my code was crashing for a completely unrelated reason :P
<saskwach> Can structs contain comptime values?
<saskwach> I'm getting a weird error trying to do it: "invalid token: '*'" when I try to put a `comptime allocator: *Allocator` in my struct.
<nrdmn> hmm, I got a "Cannot initialize MC for non-Windows COFF object files.". Does that mean llvm can't generate COFF files for non-windows OSes?
<pixelherodev> saskwach, that's because your syntax is wrong.
<pixelherodev> It's `name: comptime type`
<nrdmn> I tried to compile something with x86_64-unknown-uefi-msvc-coff
<pixelherodev> Not `comptime name: type`
<saskwach> But in function arguments it's `comptime name: type`?
<pixelherodev> ... that's actually a good point
<pixelherodev> Right now they're different though
<saskwach> Good to know.
<saskwach> andrewrk, it looks like that's about implementing the allocator at comptime. I'm just trying to store which one was chosen in the struct.
<andrewrk> that should be fine
<saskwach> Yep, it works now; just surprising to have `comptime allocator: *Allocator` in the `new` method and `allocator: comptime *Allocator` in the struct definition.
<andrewrk> `allocator: comptime *Allocator` the comptime is redundant here and I think there is a proposal to make such a redundant thing be an error
<andrewrk> expressions which have expected type of `type` are always comptime evaluated
<saskwach> Ah, I get it.
<andrewrk> there's no such thing as comptime struct fields, but that is in fact planned
<saskwach> Ok, so if the struct field's type is of type type, it's comptime and there's nothing I can do about it. If I wanted to store "7" but at comptime, that's a planned feature?
<saskwach> Or, I guess, more usefully, if I wanted to store a function pointer.
<andrewrk> there's a good chance your use case is solved with a global const
<andrewrk> are you making a generic struct?
<saskwach> I'm making a data structure library.
<saskwach> Something stupid and easy for learning the language, not something useful.
<andrewrk> you probably want `pub const foo = bar;`. is there a reason it should be a field?
<saskwach> It's the allocator that was used to instantiate the struct. I want it to know how to make more of itself (or free itself) without having every function get passed an allocator.
<saskwach> s/function/method
waleee-cl has quit [Quit: Connection closed for inactivity]
lunamn_ has quit [Ping timeout: 240 seconds]
lunamn has joined #zig
jjido has joined #zig
<andrewrk> saskwach, have a look at the implementation of std.ArrayList
<saskwach> will do
<saskwach> Yeah, that's exactly what I'm doing. Glad it works.
<andrewrk> it's almost like this musl code is trying to use error sets:
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<pixelherodev> Heh :P
<pixelherodev> Are macros ignored in @cImport blocks?
<pixelherodev> Seems both macros and typedefs don't work...
<andrewrk> macros and typedefs work, if they result in an actual prototype. translating a macro itself into something usable by zig is inherently heuristic based
<andrewrk> use --verbose-cimport to see warnings
<andrewrk> related: this would make it easier to add workarounds for macros
keithdc has quit [Ping timeout: 268 seconds]
<pixelherodev> So is 2070 an accepted proposal?
<andrewrk> no, there is an "accepted" label to mark accepted proposals
<pixelherodev> I know, wasn't sure if you were saying that one was accepted but hadn't been marked yet or something
<nrdmn> andrewrk: have you had a look at non-windows coff support in llvm? Can you tell why that is not implemented and how much work that would be?
<andrewrk> nrdmn, I have never looked into this
<saskwach> I get an error trace when I use std.debug.FailingAllocator with testing.expectError. Is this a bug?
<saskwach> testing.expectError(error,OutOfMemory, lst.push(1));
<saskwach> When I zig build test, that line causes lots of crashiness.
<saskwach> I would expect it to either print that the test failed or do nothing.
jjido has joined #zig
<andrewrk> saskwach, your expectations match mine
<Snektron> hi
<pixelherodev> Hello
<nrdmn> hi
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<pixelherodev> ... so I just realized I accidentally wrote a usable scheduler :P
<pixelherodev> Only works for cooperative multi-threading, but still
<pixelherodev> And it only runs on one CPU at present