Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Ronit Rahaman
    @RoMeAh
    So for linking to c i can just link to libc and what if i want to link to the rust stdlib?
    Bart Goossens
    @b0g2
    Essentially the same approach. You can link with libstd-XXXX.rlib from your target dependencies directory (XXXX is some hex code). However, this may require linking with some additional dependencies of libstd as well (like liblibc.rlib etc.). In case you don't want to worry about these dependencies, you can also create a Rust static system library (--crate-type=staticlib), containing all dependencies+some extra functions that you'd need. This will produce a .a (or .lib) file which you can link with.
    Ronit Rahaman
    @RoMeAh
    Thank you for all the help
    Bart Goossens
    @b0g2
    You're welcome!
    Ronit Rahaman
    @RoMeAh
    what's a good way to make strings a pointer value?
    the const_string method returns a VectorValue, is there any way of getting strings as PointerValue?
    Ronit Rahaman
    @RoMeAh
    let msg = "Hi";
    let arr_type = self.context.i8_type().array_type(msg.len() as u32);
    
    let mut chars = Vec::with_capacity(msg.len());
    
    for ch in msg.chars() {
        chars.push(self.context.i8_type().const_int(ch as u64, false));
    }
    
    let global = self
        .module
        .add_global(arr_type, Some(AddressSpace::Generic), "message");
    let string: Vec<IntValue> = chars.iter().map(|x| *x).collect();
    
    let str_array = self.context.i8_type().const_array(&string[..]);
    
    global.set_initializer(&str_array);
    
    let value = unsafe {
        self.builder
            .build_in_bounds_gep(global.as_pointer_value(), &string[..], "tmpstrval")
    };
    this segfaults when there is a unicode charecter like \0 or \n in msg, why is that so?
    Bart Goossens
    @b0g2
    You can also use builder.build_global_string(&str_val, "str").as_pointer_value(), which is shorter but does about the same as what you do.
    Bart Goossens
    @b0g2
    Not sure what build_in_bounds_gep is doing there, this function is for indexing within the string/array, but you use string itself for indexing. It should be enough to call global.as_pointer_value(). This may be the cause of the segfault.
    Ronit Rahaman
    @RoMeAh

    ok so now i do something like

        let str_type = context.i8_type().ptr_type(AddressSpace::Generic);
        let i32_type = context.i32_type();
        let printf_type = i32_type.fn_type(&[BasicTypeEnum::PointerType(str_type)], true);
        module.add_function("printf", printf_type, Some(Linkage::External));
    
    self.builder.build_call(
                self.get_function("printf").unwrap(),
                &[BasicValueEnum::PointerValue(
                    unsafe { self.builder.build_global_string("hi\0", "str") }.as_pointer_value(),
                )],
                "tmpcall",
            );

    but for some reason it causes the error of

    Call parameter type does not match function signature!
    [3 x i8]* @str
     i8*  %tmpcall = call i32 (i8*, ...) @printf([3 x i8]* @str)
    Bart Goossens
    @b0g2
    You'll need to cast @str to i8* so that it matches the function signature of printf ([3 x i8]* is a pointer to an array of length 3). Use builder.build_pointer_cast() to perform the cast.
    Instead of BasicValueEnum::PointerType(..) or BasicValueEnum::PointerValue(..) it is often more convenient to use the into() method (for example str_type.into()).
    Ronit Rahaman
    @RoMeAh
    tysm
    and do strings HAVE to be global?
    is there no other way than making them global?
    Bart Goossens
    @b0g2

    You don't have to - you can also use a const array. Or you can dynamically allocate an array and fill it up (in case the content of the string can change). To obtain a pointer for a const array without globals, AFAIK this would require stack allocation, for example as follows (I did not put a terminating zero):

    let i8_val = i8_type.const_int(0, false);
    let i8_val2 = i8_type.const_int(2, false);
    let i8_array = i8_type.const_array(&[i8_val, i8_val2]);
    let tgt_array = self.builder.build_array_alloca(i8_type, usize_type.const_int(2, false), "array");
    self.builder.build_store(tgt_array, i8_array);

    In LLVM code this gives:

    %array = alloca i8, i64 2
    store [2 x i8] c"\00\02", i8* %array

    These strings live on the stack, so they get out of scope when you leave the function. Therefore, I am not sure if anyone would implement strings like this, globals are more common (cfr. clang).

    Ronit Rahaman
    @RoMeAh
    https://github.com/BlazifyOrg/blazescript/blob/d9019de80a7bd7a2c3d8a61e1d1605a4c03c1130/crates/bzsc_llvm/src/lib.rs#L313 also i managed to work out how arguments will work but how do i actually do the function body part?
    Bart Goossens
    @b0g2
    Seems mostly fine at first sight. Only: after create_entry_block_alloca you need to jump back to the (end of the) basic block you were prior to the call. Otherwise the subsequent instructions will all end up in the entry block at the wrong location. Best is to regularly have a look at the generated LLVM code, to verify if everything is OK.
    Ronit Rahaman
    @RoMeAh
    fun add(i: int, j: int): int {
            return i + j;
    }
    return add(5, 5)

    so i wrap a main function around my code and in which i declare a function and return it but it makes some weird llvm

    ; ModuleID = 'Blazescript'
    source_filename = "Blazescript"
    
    declare i32 @printf(i8*, ...)
    
    define i128 @main() {
    entry:
    }
    
    define i128 @add(i128 %i, i128 %j) {
    entry:
      %tmpadd = add i128 %j, %i
      ret i128 %tmpadd
      %tmpcall = call i128 @add(i128 5, i128 5)
      ret i128 %tmpcall
    }

    the code for compiling functions: https://github.com/BlazifyOrg/blazescript/blob/main/crates/bzsc_llvm/src/lib.rs#L611

    Ronit Rahaman
    @RoMeAh
    alright i got it, before setting the function's block i get self.builder.get_insert_block() which returns the block to main function and at end all i do is self.builder.position_at_end(...)
    Ronit Rahaman
    @RoMeAh
    Is there any way to create FunctionValue, other than module.add_function?
    Bart Goossens
    @b0g2
    You can do for example Module::parse_bitcode_from_path and then use Module::get_function, an alternative way to end up with FunctionValues, but I am not sure if it is this that you want.
    Ronit Rahaman
    @RoMeAh
    uh actually for anonymous functions i'm a bit confused what to do? as module.add_function requires a name currently i just set the name of anonymous functions to __anonymous__
    Bart Goossens
    @b0g2
    Unless the functions have special linkage (e.g., Linkage::DLLExport, Linkage::External etc.), the actual names of the functions do not matter that much and are mostly useful for debugging/inspecting the generated bitcode. __anonymous__ as a function name is fine, it is not a problem if multiple functions have the same name.
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    Hi all, has any API design work been done for supporting invoke/landingpad?
    I've implemented what I need for my project in a fork, but would quite like to upstream it
    but we only use "catch all" and "cleanup" (with no other rules) landing pads. The api design for the general case is less obvious to me.
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    unrelated, how much work is the LLVM12 update foreseen to be?
    Daniel Kolsoi
    @TheDan64
    Feel free to PR it and I'll review
    Adding support for a new LLVM version is usually a fair bit of work
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    is there anything we can do to speed that up?
    Daniel Kolsoi
    @TheDan64
    No one has started it as far as I know
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    ok I'll give the update a go then. It looks pretty mechanical
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    llvm 12 wasn't too bad TheDan64/inkwell#253
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    I'm not sure how to interpret the CI failure there. I guess it needs to be updated to install llvm 12 too?
    Gideon Grinberg
    @gideongrinberg
    How can I use LLVM's GC with Inkwell?
    Folkert de Vries
    @folkertdev:matrix.org
    [m]
    @gideongrinberg: do you know how to do it in the abstract? From a cursory glance https://llvm.org/docs/GarbageCollection.html#abstract it could be made to work with inkwell
    e.g. there is file:///home/folkertdev/rust/inkwell/target/doc/inkwell/values/struct.FunctionValue.html#method.set_gc
    and the intrinsics can all be linked in as externs
    Daniel Kolsoi
    @TheDan64
    Yeah, we do have the set_gc method - though I don't think we've really written any tests for it. So it's possible there might be bugs. Please open and issue if you find any
    Anderson Almeida
    @Tekadon58
    how to implement 'if-else' with inkwell?
    Anderson Almeida
    @Tekadon58
    tranks <3
    Mike Harris
    @harmic
    Hi, newbie question here (sorry if it is trivial / answered elsewhere ...)
    I want to create an i64 constant, but const_int takes a u64. How does one create an i64 constant?
    programmerjake
    @programmerjake:matrix.org
    [m]
    llvm doesn't distinguish the sign of integer constants, so just use const_int with my_value as u64
    Mike Harris
    @harmic
    Thanks @programmerjake:matrix.org