Re: Some questions with D and webassembly
On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote: In webassembly, there's a type called `externref`, which opaquely represents a javascript object. So, you could do this for example, with this javascript: ```js class Foo { constructor(x) { this.x = x; } } const imports = { env: { fooNew: (x) => new Foo(x), fooX: (foo) => foo.x, fooSetX: (foo, x) => { foo.x = x; } } } WebAssembly.instantiateStreaming(fetch("./foo.wasm"), imports).then(module => { let foo = module.instance.exports.f(); console.log(foo.x); // 5 module.instance.exports.g(foo); console.log(foo.x); // 8 }); ``` and this webassembly: ```wat (module (import "env" "fooNew" (func $fooNew (param i32) (result externref))) (import "env" "fooX" (func $fooX (result i32))) (import "env" "fooSetX" (func $fooSetX (param externref) (param i32))) (func (export "f") (result externref) i32.const 5 call $fooNew) (func (export "g") (param $foo externref) local.get $foo i32.const 8 call $fooSetX)) ``` 5 and 8 get logged. Equivalent D to the webassembly part would be: ```d extern(C): // how to get this externref type? externref fooNew(int); externref fooX(externref); void fooSetX(externref, int); externref f() { return fooNew(); } void g(externref foo) { fooSetX(foo, 8); } ``` problem being, there exists no `externref` type. So how would you achieve it with ldc2? B) In the javascript WebAssembly API, you can pass in memory like so: ```js const imports = { "mem": new WebAssembly.Memory({ initial: 1 }) } WebAssembly.instantiateStreaming(fetch("bar.wasm"), imports, module => { ... }); ``` then in WebAssembly ```wat (import "mem" (memory 1)) ``` so how could I do that in D? That is, I want the memory that D uses to be accessible to javascript (this way I can pass pointers between JS and D) https://discourse.llvm.org/t/rfc-webassembly-reference-types-in-clang/66939 it says it is an opaque type, maybe just need to be ``void*``? Also there are new intrinsics, maybe you can define them like this: ```D alias externref_t = void*; pragma(LDC_intrinsic, "llvm.wasm.table.set.externref.i32") extern(C) void llvm_wasm_table_set_externref(void*, int, externref_t); pragma(LDC_intrinsic, "llvm.wasm.table.get.externref.i32") extern(C) externref_t llvm_wasm_table_get_externref(void*, int); ```
Passing and returning arguments by ref
Let's say we have two classes, A and B. The latter has a dynamic array of X and type X has an add() method that can be used to append elements (of type C, another struct) to X's own dynamic array of C. So it's something like the following: ```d struct C {} struct X { C[] cs; void add(C c) { cs ~= c; } } class A { X x; void mfd(ref B b) { // manipulate A.x and one B.xs (returned by B.x1() // by calling another member function // that calls X.add(some C) } } class B { X[] xs; this() { xs.length = 1; } ref X x1() { return xs[0]; } } ``` After A and B are instantiated and A.mfd() is called, the changes to A.x are visible in main. However, although the changes to the X returned by B.x1() are visible while A.mfd() executes, the B.xs[0] is unchanged after it returns. My understanding was that since A, B and X[] are all reference types, this ought to work, but obviously something is missing.
Re: Terminating the process of a running LDC2 compiler.
On Wednesday, 1 March 2023 at 11:38:11 UTC, realhet wrote: Hello, Is it safe to kill an ongoing LDC2 process on Windows? My situation is this: - I launch 8 LDC2 compilation command lines on 8 DLang source files. - One of them has a compilation error and quits. - At this point I wait the completion of the other threads, but it would be faster to kill all those threads, fix the error, and run the multithreaded compilation again. Is it safe to kill those processes, or would it be unreliable (because of the integrity of environment variables, and/or cached temp files)? Thank You! We don't know what you mean by your definition of safe unfortunately
Re: Terminating the process of a running LDC2 compiler.
On Friday, 3 March 2023 at 14:33:08 UTC, Imperatorn wrote: We don't know what you mean by your definition of safe unfortunately For example killing ldc2.exe while it writes some cached temp files. And when the next time it tries to load those corrupted files, it will crash, or generate wrong output.
Re: Passing and returning arguments by ref
On 3/3/23 06:03, Joe wrote: > My understanding was that since A, B and X[] are all reference types, > this ought to work, but obviously something is missing. Think may be due to D not having reference variables. Sometimes one needs to use pointers. I find the following a simpler (and complete ;) ) example. foo() returns by ref and indeed, the change made to its return value is visible in main. However, the same foo() is later called to initialize hopefullyRef but not the change made to that variables is not reflected in the array. (By the way, the example could be written without an array as well.) struct S { int i; void change() { ++i; } } ref S foo(S[] arr) { return arr[0]; } void main() { auto arr = [ S(1) ]; // Ok, this operation changes arr[0] foo(arr).change(); assert(arr[0].i == 2); // This one changes the local variable auto hopefullyRef = foo(arr); hopefullyRef.change(); assert(hopefullyRef.i == 3); // The array is still 2 assert(arr[0].i == 2); } hopefullyRef in just an int. The following definition of the hopefullyRef variable would cause the array element be changed: // Now an S* (note & on the rigth-hand side) auto hopefullyRef = &foo(arr); // Now hopefullyRef is an S*, not an S // Same as before hopefullyRef.change(); assert(hopefullyRef.i == 3); // Now the array is affected (3, not 2) assert(arr[0].i == 3); Ali
Re: Some questions with D and webassembly
On Friday, 3 March 2023 at 13:42:55 UTC, ryuukk_ wrote: On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote: [...] https://discourse.llvm.org/t/rfc-webassembly-reference-types-in-clang/66939 it says it is an opaque type, maybe just need to be ``void*``? Also there are new intrinsics, maybe you can define them like this: ```D alias externref_t = void*; pragma(LDC_intrinsic, "llvm.wasm.table.set.externref.i32") extern(C) void llvm_wasm_table_set_externref(void*, int, externref_t); pragma(LDC_intrinsic, "llvm.wasm.table.get.externref.i32") extern(C) externref_t llvm_wasm_table_get_externref(void*, int); ``` Using `void*` doesn't appear to work (and looking at the generated wasm it seems to reduce it to `i32`, which is not the right type unfortunately). I guess what I could do is have a global array in js which stores all objects I'll need to access, then just access them via the index into that array but that feels like a hack especially when `externref` is a thing that exists.
Can't load FreeImage.dll with Windows
I've tried distilling the problem to its very essence. I downloaded the FreeImage.dll from https://freeimage.sourceforge.io/download.html to the following directory: where /R c:\ FreeImage.dll c:\Users\Admin\Downloads\FreeImage3180Win32Win64\FreeImage\Dist\x64\FreeImage.dll dir c:\Users\Admin\Downloads\FreeImage3180Win32Win64\FreeImage\Dist\x64\FreeImage.dll 07/31/2018 12:23 PM 6,942,208 FreeImage.dll 1 File(s) 6,942,208 bytes dependency "bindbc-freeimage" version="~>1.0.0" versions "FI_318" but when I try to load the dll with the bindbc-freeimage package provided loadFreeImage function, all I get is no library found: writeln("The dub.sdl file of this project expects FreeImage version ", fiSupport); immutable FISupport fiLib = loadFreeImage("c:\\Users\\Admin\\Downloads\\FreeImage3180Win32Win64\\FreeImage\\Dist\\x64\\FreeImage.dll"); writeln("loadFreeImage returned: ", fiLib); OUTPUT --- The dub.sdl file of this project expects FreeImage version fi318 loadFreeImage returned: noLibrary I also tried: loadFreeImage(`c:\Users\Admin\Downloads\FreeImage3180Win32Win64\FreeImage\Dist\x64\FreeImage.dll`); and loadFreeImage(`c:/Users/Admin/Downloads/FreeImage3180Win32Win64/FreeImage/Dist/x64/FreeImage.dll`); but got same results. Also tried version="~>1.0.2"
Re: Some questions with D and webassembly
On Friday, 3 March 2023 at 18:34:24 UTC, TheZipCreator wrote: On Friday, 3 March 2023 at 13:42:55 UTC, ryuukk_ wrote: On Friday, 3 March 2023 at 03:32:37 UTC, TheZipCreator wrote: [...] https://discourse.llvm.org/t/rfc-webassembly-reference-types-in-clang/66939 It looks like this needs some more compiler support. Please submit the feature request (including the link to this LLVM page) on LDC's github page. cheers, Johan
Re: Can't load FreeImage.dll with Windows
What happens if you put the dll next to your executable, does it find it?
Re: Passing and returning arguments by ref
Thanks, Ali. On Friday, 3 March 2023 at 18:09:01 UTC, Ali Çehreli wrote: Think may be due to D not having reference variables. Sometimes one needs to use pointers. Ah! I'm about five chapters away from Pointers ;-). Actually, I had tried changing B.x1() to: `ref X x1() { return &xs[0]; }` but the compiler didn't accept it. It's a bit weird that by taking the address of calling B.x1() and thus getting an X*, I had to *dereference* that to pass it to the helper function of A.mfd() which actually takes a `ref C` argument.
Re: Can't load FreeImage.dll with Windows
On Friday, 3 March 2023 at 19:44:17 UTC, ryuukk_ wrote: What happens if you put the dll next to your executable, does it find it? Good idea. I copied the dll into same directory as the executable and changed loadFreeImage to immutable FISupport fiLib = loadFreeImage(); And I get the same noLibrary result.
Re: Can't load FreeImage.dll with Windows
I went ahead and tried to reproduce your setup (this worked). Used FreeImage3180Win32Win64.zip and recent dmd & ldc. ```json { "authors": [ "alpha" ], "copyright": "Copyright © 2023, alpha", "description": "A minimal D application.", "license": "proprietary", "name": "whatmeworryfreeimage", "dependencies": { "bindbc-freeimage": "~>1.0.2" }, "versions": ["FI_318"] } ``` ```d import std.stdio; import bindbc.freeimage; void main() { FISupport ret = loadFreeImage("FreeImage/Dist/x64/FreeImage.dll"); if(ret != fiSupport) { if(ret == FISupport.noLibrary) { writeln("no"); } else if(FISupport.badLibrary) { writeln("bad"); } } else { writeln("good"); } } ``` Directory layout: ``` . ├── dub.json ├── FreeImage │ └── Dist │ ├── x32 │ │ └── FreeImage.dll │ └── x64 │ └── FreeImage.dll └── source └── app.d ```
Re: Can't load FreeImage.dll with Windows
On Friday, 3 March 2023 at 19:07:14 UTC, WhatMeWorry wrote: loadFreeImage(`c:\Users\Admin\Downloads\FreeImage3180Win32Win64\FreeImage\Dist\x64\FreeImage.dll`); is your application build 64 bit too?
Re: Passing and returning arguments by ref
On 3/3/23 12:45, Joe wrote: > I had tried changing B.x1() to: > >`ref X x1() { return &xs[0]; }` > > but the compiler didn't accept it. Yeah, that wouldn't work because the return expression is an X*. Even though 'ref' is implemented as a pointer behind the scenes, that syntax is not legal. > It's a bit weird that by taking the address of calling B.x1() and thus > getting an X* Agreed but that's how it is. Taking the address of a reference produces an X*. > I had to *dereference* that to pass it to the helper > function of A.mfd() which actually takes a `ref C` argument. Yep, all of that makes sense. :) Ali
Re: Desiring bool any_key_pressed()
On Friday, 3 March 2023 at 03:38:56 UTC, Daren Scot Wilson wrote: Here is a very simple version of the program I'm working on. Is there a way to write is_any_key_pressed() that doesn't block, doesn't require the Enter key, and doesn't require dragging in any complex libraries or dealing with low-level stuff like ioctl()? Is there nothing in Phobos that provides the needed functionality? See this SO thread:https://stackoverflow.com/q/1798511 Essentially the os/terminal is buffering your input and that needs to be configured. getChar just reads from what's in stdin.