-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unrecognized file extension lib #15
Comments
Can you try with I have never tried to run spasm on windows to be honest. But I don't see why it shouldn't work. |
Same result. I'm not sure if it's about spasm or dub. Can be either one. |
I will spin up my Windows machine this weekend to try to see what is going on. |
Adding
I wonder why the compiler tries to import those? |
It could be that you forgot to add |
Nope. Its the |
I tried on my windows box, but got the same errors. I suggest to make a minimal test case (preferably without spasm, just betterC), and then ask the ldc or probably druntime folks whats going on. |
I receive the same error when running |
Of course, should have occured on me to do already. |
Building a minimalistic wasm binary revealed that DUB appends .exe to the object binary name instead of .wasm. By taking the ldc2 invocation of DUB, replacing However, doing the same to the dom example won't remove the errors. Something is importing different stuff on Windows than on other platforms. |
Interesting. So the dom example complains about Hmm.. I will have to look into this some more. |
That's correct
Of course, it can be some of the dependecies, not spasm itself. |
I think I got a bit forward. It seems that two changes are needed: 1: For some reason, DUB imports modules from dependency packages needlessly. I got around this by commenting out global imports and classes on 2: My LDC did not like your declaration of After these changes, the dom example compiled. I am not yet sure if it works, because my browser won't let me to just import the autogenerated |
That is great! I hope to find some time later this week to try to incorporate your changes, The Although now that you set the extension to |
Didn't finish today. (I'm not trying anymore to get the example working, but my production code. It's more onerous because I have many functions in D that I need to call from JavaScript.) |
Let me know if you need some pointers calling D from Javascript. It's pretty straightforward, but when you are dealing with strings, D structs or float arrays I have some experience with that. |
What I'm going to ask may be a canditate for thedailywtf.com, but here goes anyway. So I got the idea that I want to avoid using npm/npx, to avoid having to learn a new program. So I copied contents of the autogenerated Because of that, the init: () => {
fetch("dmodule.wasm")
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.instantiate(buffer, { imports: jsExports }))
.then(obj =>
{ spasm.instance = obj.instance;
obj.instance.exports._start();
window.alert("spasm ready");
})
.catch(error => {window.alert(error);})
} LATER NOTE: Now it apparently finds and loads the WebAssembly, but it does not work: |
By avoiding npm you are only making it more difficult for yourself. I would really suggest to go with npm. You can include your own code in It would be nice to have alternative bootstraps, but it is at the bottom of the backlog. (e.g. https://pax.js.org/) I can still give you some tips on getting something to run, but you are pretty much on your own. Mdn has some good docs on WebAssembly and some good examples. See https://developer.mozilla.org/en-US/docs/WebAssembly
Looks good to me. For performance you could use instantiateStreaming instead.
Depending on what you want to do with spasm you might need those modules. I understand that you are trying to run the code directly in the browser and are thus avoiding JS ES6 modules. But it is like a bit like going against the grain.
The code looks ok. From the compile error you get I can only conclude that the |
Webassembly studio binaryen entered infinite loop. So I decided to compare |
However, the dom example |
Indeed, the problem was DUB trying to build a library configuration. I now managed to get the first D function call verifiably to work. |
Great. Any tips that I can update the README.md with, for fellow windows users? If I read the thread correctly it would be to add |
For the And also, I don't know if this is Windows specific but you need to make sure DUB is building an application, never a library. Otherwise it won't be valid wasm. |
BTW in case you want to know: today, I have finished porting all the parts of my application that formerly ran on Emscripten, and merged the result to master. Your library will very soon be in commercial "production". |
That is awesome! I am a little curious, any change of showing the source? Or maybe you could describe what parts of spasm you are using? |
I cannot show the source as a whole, since it's a propietary piece, but the work in general is no secret so I can freely talk about it, and I don't think anybody will mind if I include some snippets. A small company and I'm the only programmer so no rigid rules. It is a product preview program for salesmen, that runs in a browser. Only locally, currently, but the idea is to put it in the Internet someday, so we want to embed the program in HTML. I did not like the idea about doing a major application in JavaScript, so I use Bridge.Net (that compiles C# into JS) instead. If you were wondering how can I be so bad at JavaScript development, now you know why. In summer 2018, I took a major effort to embed D code in the application, fairly much just because I wanted to. I used https://github.com/cosinus2/dlang-emscripten-demo as my base example, which meant fooling LDC to think it was compiling to X86 but only compiling to LLVM bytecode and feeding that to Emscripten. I had to copy every Porting the D code to Spasm should cut down the overall number of problems like those I described. Now at least I can use a more up-to-date LDC, and it knows it's compiling to WASM. Plus, there's potential to command JavaScript classes from D code. I haven't done that yet, since with my lack of JavaScript skills and lack of an existing library to help with interfacing, writing JS bindings just for Emscripten D didn't seem worthwhile. But with this library that as both examples and code to take as a base, it may be relevant in the future. One thing that consumed a big deal of time was that unlike Emscripten, Spasm does not have malloc/free, so I wrote up my own (I did want to free memory after use): enum memPageAmount = 0x200u;
enum memSizeClasses = 13u;
enum pageSize = 1u << memSizeClasses-1;
__gshared ushort[memSizeClasses] lastMemoryPages;
__gshared uint[memPageAmount] heapMap;
__gshared void[pageSize][memPageAmount] heap = void;
export extern(C) void* malloc(size_t amount)
{ if (amount == 0) return null;
foreach(allocSize; memSizeClasses.iota)
if (amount <= (1u << allocSize))
foreach(pageI; lastMemoryPages[allocSize].iota(lastMemoryPages[allocSize] + memPageAmount).map!(i => cast(short)i))
{ pageI %= memPageAmount;
void* result;
if
( heapMap[pageI] >= 0x0100_0000u >>> allocSize * 2
&& heapMap[pageI] < 0x0300_0000u >>> allocSize * 2
&& ~heapMap[pageI] & 0x0000_0FFFu >>> allocSize
)
{ result = &heap[pageI][0] + ((heapMap[pageI] & 0xFFF >>> allocSize) + 1) * (1u << allocSize);
//merkitsee muistikarttaan lohkon käyttöönoton.
heapMap[pageI]++;
} else if (heapMap[pageI] == 0)
// varaamaton sivu. Eiköhän oteta käyttöön.
{ heapMap[pageI] = 0x0100_0000u >>> allocSize * 2;
result = heap[pageI].ptr;
}
else continue;
assert(result >= heap.ptr && result < heap.ptr + memPageAmount);
lastMemoryPages[allocSize] = pageI;
assert(heapMap[pageI] != 0);
return result;
}
auto pagesNeeded = (amount - 1) / pageSize + 1;
//yli muistisivun kokoisen alueen varaus
size_t result = 0;
foreach (canditate; heapMap[].slide(pagesNeeded).filter!(potentialAlloc => potentialAlloc.all!(page => page == 0u)))
{ if (canditate.all!(page => page == 0u)) goto foundArea;
result++;
}
//muisti loppu
return null;
foundArea:
heapMap[result] = 2u;
foreach(ref pageMark; heapMap[].drop(result + 1).takeExactly(pagesNeeded-1))
{ pageMark = 3u;
}
return heap[result].ptr;
}
export extern(C) void free(const(void)* cAllocation)
{ //Oletettavasti tälle funktiolle välitetty osoitin dumpataan jorpakkoon heti jälkeenpäin,
//joten tämä tyyppimuunnos ei luultavasti aiheuta ongelmia.
auto allocation = cast(void*) cAllocation;
if (allocation == null) return;
assert(allocation >= heap.ptr && allocation < heap.ptr + memPageAmount, "free() ei osoita kekoon!");
ptrdiff_t allocAddr = allocation - &heap[0][0];
size_t pageI = allocAddr / pageSize;
size_t pageOffset = allocAddr % pageSize;
assert (heapMap[pageI] != 0, "Yritetään vapauttaa jo valmiiksi varaamatonta muistia");
assert (heapMap[pageI] != 3, "Muistin vapautus ei osoita varatun pätkän alkuun");
foreach(allocSize; memSizeClasses.iota) if
( heapMap[pageI] >= 0x0100_0000u >>> allocSize * 2
&& heapMap[pageI] < 0x0300_0000u >>> allocSize * 2
)
{ /+assert
( heapMap[pageI] >= cast(ulong)pageOffset * pageSize + 0x0100_0000u >>> allocSize * 2,
"Yritetään vapauttaa jo valmiiksi varaamatonta muistia"
);+/
assert (pageOffset % 1u << allocSize == 0, "Muistin vapautus ei osoita varatun pätkän alkuun");
//kirjoitetaan muistiin: yksi vapautettu.
heapMap[pageI] += pageSize >>> allocSize;
if (heapMap[pageI] > 0x0200_0000u >>> allocSize * 2) heapMap[pageI] = 0;
return;
}
assert (heapMap[pageI] == 2u);
heapMap[pageI] = 0;
foreach(ref pageMark; heapMap[pageI+1 .. $].until!(a => a!=3u)) pageMark = 0;
} (Comments/Asserts are Finnish) Example of function used by application logic: // Tulkitsee päivämäärät kahdesta merkkijonosta, ja palauttaa tuloksessa niiden keskinäisen järjestyksen
// (negatiivinen = lukujärjestys, 0 = samankokoiset)
// Ei tällä hetkellä osaa käsitelä oikein lukuja, joissa on nolla merkitsevimpänä numerona
// (eikä tätä kirjoitettaessa ole tarvettakaan sille)
export extern (C) int cmpDates(Handle a, Handle b)
{ auto strings = [a, b].staticArray[].map!(jsStr => jsStr.spasm_get__string).staticArray!2;
scope (exit) foreach(str; strings) str.ptr.free;
auto numbers = strings[]
.map!
( str => str
.byCodeUnit
.retro
.splitter!((a, b) => a.isDigit == b.isDigit)(' ')
);
if (auto result = numbers[0].walkLength - numbers[1].walkLength) return result;
for(;!numbers[0].empty;numbers[0].popFront, numbers[1].popFront)
{ if (auto result = numbers[0].front.length - numbers[1].front.length) return result;
if (auto result = numbers[0].front.cmp(numbers[1].front)) return result;
}
//samat luvut.
return 0;
} If you're wondering, I have rewired I let anybody to use these examples under Boost license, but except bugs if you do. |
Thats pretty cool. Glad to see that it simplified your toolchain.
Yes, I was about to comment on it :) I really need to solve that memory management. But without GC and with things like RCString, its a little tough. |
Wrt. the original issue that hasn't been resolved: the thing is that dub uses extensions I haven't checked whether LLD supports a normal |
I favor making dub target aware. Besides the |
I prefer doing both. If conflating |
Same problem here. Is there any solution yet? |
On windows you'll need to use the |
The proper solution would be to add the |
while compiling dom example with this command: I get this: And note that I am using the dub binary that I ve just compiled from the ~master branch since I saw that your issue dlang/dub#1749 ended up with some commits by @kinke |
If you run |
That's a dub warning that can safely be ignored. |
wasm32 is listed. Ok I am igroring that warning. But I am also getting this similar to dukc's error |
It must be a ldc issue since I am facing the same problems when I try to compile this example involving in emscripten also: https://theartofmachinery.com/2018/12/20/emscripten_d.html |
That's something completely different, limited WebAssembly support in druntime (no C runtime yet), which @skoppe is working on. |
Those errors are because something is pulling in druntime, which doesn't support wasm yet. Spasm and the examples are building on linux with the latest ldc 1.19.0 as evidenced by the CI https://github.com/skoppe/spasm/runs/365457809 so I suppose there is an error in your setup. What does your |
Ok. this is what I do now: I boot into my ubuntu partition (16.04 64 bit) and I get: |
Yeah, don't add
You might need I am using |
Hey thank you! |
For Spasm to work at Windows (until DRuntime port is finished) you need to patch dub dependencies for this to work. My comment from earlier:
You need only to do the first piece, as second is now merged into spasm. Also use the already mentioned No quarantee these will work anymore though, as it's roughly six months since I last built on Windows. |
Any news on this? I would love to give this library a spin on Windows. |
The dub issue should have been fixed almost a year ago with dlang/dub#1755, which has landed in dub v1.18. |
Yes, I was waiting for the OP to close this, but will do this now. The instructions are in the readme, for build instructions it refers to https://github.com/skoppe/spasm/blob/master/BUILDING.md |
Go ahead, I'm not in a position to decide when it's fixed since I don't code on Windows anymore. |
Looks like these errors still show up on Windows: #15 (comment) |
The errors in that comment are unrelated to this issue. If you get them something is going wrong with betterC, as the compiler is trying to pull in druntime, which it shouldn't. If you can paste your |
I will do that. |
When I try to build the dom example (in the dub cache, without moving it away), using
dub build --compiler=ldc2
, dub will complainI have had dub to run the bootstrap-webassembly subpackage, and there is a
spasm.lib
in the spasm project root directory. Operating system is Windows 10, compiler is LDC2 v.1.14.0 and dub version is 1.13.0.ldc2 invocation dub tries is:
Has anybody else here experienced this error? Thanks.
The text was updated successfully, but these errors were encountered: