/* függvénykönyvtár behúzása, stb módra, nem kell linkelni semmivel */
#define WA_IMPLEMENTATION
#include "wa.h"
/* wasm bináris bitkolbásza, fordította "Clang --target=wasm32", yours truly */
uint8_t wasmbinary[1234] = { ... };
/* futás idejű linkelő tábla és kontextus */
RTLink link[] = {
/* név ki be proto */
{ "malloc", &malloc, 0, WA_ll }, /* host -> WASM */
{ "realloc", &realloc, 0, WA_lll }, /* host -> WASM */
{ "free", &free, 0, WA_vl }, /* host -> WASM */
{ "add", NULL, -1, WA_fff }, /* WASM -> host */
{ "sub", NULL, -1, WA_fff }, /* WASM -> host */
{ "globvar", &globvar, 0, WA_i }, /* megosztott változó */
{ 0 }
};
Module m;
/* betöltés, inicializálás */
wa_init(&m, wasmbinary, 1234, link);
/* egy WASM függvény hívása C-ből. Elöször kikeressük a szimbólumot (ha nem felejtettük el,
hogy a link[] tömb hányadik sora, akkor keresgélés helyett csak simán O(1) lekérés) */
int addfunc = cavinton_klub? wa_sym(&m, "add") : link[3].fidx;
/* bemeneti paraméterek átadása és hívás */
wa_push_f32(&m, 1.0);
wa_push_f32(&m, 2.0);
ret = wa_call(&m, addfunc);
printf("Eztetet adta vissza: %f\n", ret.f32);
/* többet nincs mit elmondani, kérem kapcsoljaki */
wa_free(&m);
Ennyi. Ennél faékebb egyszerűségű és könnyebben integráható API-t nem bírtam kiagyalni. Négy függvény init / push / call / free és kész (oké, a push-ból van több változat, mindenféle típushoz, de akkor is 12 függvény cakk-um-pakk). A valós idejű linkelés meg egy struct tömbbel zajlik, aminek négy mezője van:
- első a szimbólum (UTF-8 sztring)
- második egy memóriacím, ezt te adod meg akkor, ha a WASM-nek akarod átadni
- harmadik egy függvényindex, ezeket meg a WASM adja meg, hogy meg tudd hívni
- negyedik meg egy prototípust kódoló bitmaszk
Bármelyik globális WASM változó láthatóvá tehető host oldalon, ha felvesszük a táblába a WASM szimbólum nevét egy host memóriacímmel. Másik irány is működik, ekkor "extern"-nek kell definiálni a WASM modulban.
De ami biztonság szempontjából nagyon fontos, a WASM szkript nem tud semmi mást meghívni, csak azokat, amik szerepelnek a listán.
Viszont ott bármilyen függvénnyel működik, de azért lehetőség van saját dispatcher megadására is egy WA_DISPATCH define-nal.
Szabad és Nyílt Forráskódú, licensze a megengedő MIT.- 1082 megtekintés
Hozzászólások
Wow! Szép! Játszadozok WASM-mal, bár én csak saját megbízható kódot futtatok böngészőben, ezért elég volt eddig C-ből natívra fordítani, hogy böngészőn kívül is futtassam.
Amire hasznos lehetne még, ha tudnánk debuggolni is a WASM-ot. Lehetne szerinted a megoldásoddal?
- A hozzászóláshoz be kell jelentkezni
én csak saját megbízható kódot futtatok böngészőbenEz nem az. Ez arra való, hogy behúzod ezt az egy fejlécfájlt a forrásodba, és akkor a programodban tudsz WASM binárisokat futtatni. (Azaz olyan, mintha a programod lenne a böngésző.)
ezért elég volt eddig C-ből natívra fordítani, hogy böngészőn kívül is futtassam.A natív nem mindig opció. Ez tipikusan arra van, amikor szkriptet kell tudnod futtatni a programodból. Kb. mintha Luát ágyaznád be, csak annál sokkal kissebb és egyszerűbb. Erre kézenfekvő bájtkódot használni, mert nem kell hozzá lexer, tokenizáló, AST, fittyfene. A rendelkezésre álló bájtkód fajtákból meg a WASM azért jó, mert rengeteg nyelvet le tudsz fordítani WASM bájtkódra, pl. Javascriptet, de akár Luát is. Szóval ha van egy ilyen bájtkód VM-ed, akkor bármilyen szkriptet tudsz vele futtatni, ráadásul oprendszer és platform függetlenül.
Amire hasznos lehetne még, ha tudnánk debuggolni is a WASM-ot. Lehetne szerinted a megoldásoddal?Hogyne. Ha defineolod a DEBUG-ot, mielőtt behúznád a wa.h-t, akkor ilyen részletes kimenete lesz. Ez a teljes WASM binárist kidebuggolja neked (amolyan objdump / readelf szerűen), valamint minden egyes API hívás is generál egy kimenetet. Ha magát az utasításvégrehajtást akarnád lépésenként debuggolni, az is egyszerűen belerakható, mivel nagyon kicsi és átláható az egész forrása: a wa_interpret-ben van egy ciklus, ez olvassa be és értelmezi egyesével a bájtkódot (minden iteráció pontosan egy utasítást hajt végre). Ide kell csak berakni pár printf-et, és máris pontosan láthatod, mikor mi hajtódik végre. De igazából még egy rendes debugger is rittyenthető lenne köré egész könnyedén. Annyi módosítás kellene csak, hogy a wa_interpret-ből ki kell venni a while-t és átnevezni wa_step-re, aztán meg berakni helyette egy ilyen új wa_interpret-et:
static int wa_interpret(Module *m) {
while(!m->err_code && m->pc < m->byte_count)
wa_step(m);
}
Ezzel teljesen működőképes és visszafelé kompatíbilis maradna, a debuggernek meg csak annyi lenne a dolga, hogy a wa_interpret helyett a wa_step-et hívogná egyesével, a hívások között meg kidumpolhatja a Module-t. Ja, simán megoldható, és nem is lenne hülyeség egy fullos WASM debuggert csinálni belőle.- A hozzászóláshoz be kell jelentkezni
Offtopic: ret, m, wa, wa_push_f32, fidx, stb. csodálatos nevek, amik kiakasztanak. Mintha számítana, hogy hány karakter a változó, de legalább brutálisan ront az olvashatóságon. ... tudom az összes kód ilyen...
- A hozzászóláshoz be kell jelentkezni
Mintha számítana, hogy hány karakter a változóIgen, nagyon is számít. Nem tudtam volna másfél nap alatt nulláról megcsinálni ezt a libet, ha "m" helyett mindig az gépeltem volna, hogy "ModuleInstantiatedFromWASMBinary". Gyorsan gépelek, de azért ennyire még én sem, hetekig tartott volna.
de legalább brutálisan ront az olvashatóságon.Offtopik: szerintem meg épp hogy drasztikusan javít az olvashatóságon, ki nem állhatom az olyan forrásokat, ahol fél képernyőt elfoglal egyetlen változónév. Sokkal könnyebben átlátható az "fidx", mint az "IndexOfTheFunctionToBeCalled". Az előbbire elég csak rápillantanom, míg utóbbinál megakadok, és oda kell figyelnem, hogy végigolvassam (mert mi van ha nem is az a változó van ott, hanem mondjuk az "IndexOfTheFunctionToBeExported"?)
- A hozzászóláshoz be kell jelentkezni
Nem arról van szó hogy hosszúnak kell lennie, hanem arról lényegretörő legyen és könnyen olvasható. Nyilván sok gyakorlás kell ahhoz hogy pont jó neveket találjunk ki. Én amikor kódolok minden második leütésem a tab, mert automatikusan kitalálja hogy mit akarok.. Így nem érzem hogy számítani, hogy hány karakter a változó, no meg 90-es években is volt ugye a ctrl-c+v.
Nem szeretek másokat szívatni, az egybetűs változónevekkel, így mástól is elvárom hogy ne szívasson. Programozás nem gyors író verseny, fontosabb számomra a kódminőség.
Kapcsolódó: Tiszta kód elvek - Összefoglaló - Elnevezések
Nyilván amit a környezet vagy a külső lib ad azt nem tudod befolyásolni. Őket se értem, de ez van. :)
- A hozzászóláshoz be kell jelentkezni
Én amikor kódolok minden második leütésem a tab, mert automatikusan kitalálja hogy mit akarok..Direkt olyan példát írtam, aminél nem működik az autocompletition. Szerintem észre se vetted, mi a küönbség a két változónév között, akkor nem írtad volna ezt (most nyilván visszaolvasod mit írtam, alaposan megfigyeled a két nevet, és közben kizökkensz jelen poszt olvasásából emiatt...) Ezen kívül semmit sem javít az olvashatóságon a tab, továbbra is baromira nehéz lesz olvasni az ilyen kódot. Egyszerűen sokáig tart, mire felismered a változóneveket. 4-5 karakteres változóneveknél elég egy pillantás is, hogy észrevedd a különbséget, 20-30 karakteres neveknél meg mindig kizökkensz, mert alapos odafigyelésre van szükség.
Nem szeretek másokat szívatni, az egybetűs változónevekkel, így mástól is elvárom hogy ne szívasson.Nehogy már ne tudd kitalálni a "Module m" definícióból és a kontextusból, hogy az "m" modult jelent. Mi abban a szivatás, hogy a leggyakrabban használt változó neve rövid, a ritkán használté meg hosszabb?
Őket se értemMégegyszer, ők is tisztában vannak vele, hogy a hosszú változónevekkel sokkal jobban szivatod az embereket, mert write-only lesz tőle a kódod, sokáig tart elolvasni, nehéz lesz dekódolni és értelmezni. Ne a változónevekkel akard elmagyarázni, hogy mit is csinál a programod. Teszt: vedd észre a különbséget: fidx gidx vs. Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu Taumatawhakatangihangakoauauotamaloaturipukakapikimaungahoronukupokaiwhenuakitanatahu Mennyi ideig tartott az első és mennyi ideig a második esetben? (Nem tenyereltem rá a billentyűzetre, ez egy létező név.)
- A hozzászóláshoz be kell jelentkezni
Tetszik, meg fogom nézni. Már csak az a kérdés, hogy honnan van ennyi időd. :)
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni