├── LICENSE ├── Makefile ├── README.md ├── c-test.html ├── cfile.c ├── template.ht └── wasmtemplate.c /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 CNLohr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all : c-test.html 2 | 3 | C_S:=cfile.c 4 | 5 | cfile.wasm : $(C_S) 6 | clang -Wl,--no-entry,--allow-undefined,--export=runAnimation,--export=runTimer,--export=reenterAnimation,--export=reenterTimer,--export=submitFrame,--export=timerSleep -nostdlib --target=wasm32 -o $@ $(C_S) 7 | wasm2wat -o cfile.wat cfile.wasm 8 | sed -i 's/$$start_unwind/$$asyncify_start_unwind/g' cfile.wat 9 | sed -i 's/$$stop_unwind/$$asyncify_stop_unwind/g' cfile.wat 10 | sed -i 's/$$start_rewind/$$asyncify_start_rewind/g' cfile.wat 11 | sed -i 's/$$stop_rewind/$$asyncify_stop_rewind/g' cfile.wat 12 | sed -i 's/(import "env" "start_unwind"/(import "asyncify" "start_unwind"/g' cfile.wat 13 | sed -i 's/(import "env" "stop_unwind"/(import "asyncify" "stop_unwind"/g' cfile.wat 14 | sed -i 's/(import "env" "start_rewind"/(import "asyncify" "start_rewind"/g' cfile.wat 15 | sed -i 's/(import "env" "stop_rewind"/(import "asyncify" "stop_rewind"/g' cfile.wat 16 | wat2wasm -o cfile.wasm cfile.wat 17 | wasm-opt --asyncify $@ -o $@ 18 | 19 | %.wasm.b64 : %.wasm 20 | cat $^ | base64 > $@ 21 | 22 | c-test.html : template.ht cfile.wasm.b64 wasmtemplate 23 | ./wasmtemplate template.ht cfile.wasm.b64 > $@ 24 | 25 | 26 | wasmtemplate : wasmtemplate.c 27 | gcc -o $@ $^ 28 | 29 | 30 | clean : 31 | rm -rf wasmtemplate cfile.wasm.b64 cfile.wasm cfile.wat 32 | 33 | clean_all : clean 34 | rm -rf c-test.html 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SUPERSEDED NOTICE 2 | 3 | This project is in the process of being superseded by this one: https://github.com/cnlohr/rawdrawwasm/ 4 | 5 | # wasm_integrated 6 | An eample of how you can fully integrate wasm into a webpage. No need for feteching or any of that jazz. What if someone's on a connection with a lot of latency? What if you want to load a wasm app from your hard drive directly, like double-clicking on the HTML file? Whelp, this is that. 7 | 8 | Check it out live, here: [link](https://cnlohr.github.io/wasm_integrated/c-test.html) 9 | 10 | It's a demo of how to integrate the whole shebang into one small HTML file. Get your small .c file compiled into wasm and loaded without any hocus pocus. 11 | 12 | ``` 13 | # make clean all 14 | rm -rf wasmtemplate cfile.wasm.b64 cfile.wasm 15 | /home/cnlohr/git/emsdk/upstream/emscripten/emcc -o cfile.wasm cfile.c -s EXPORTED_FUNCTIONS='["_testcallback","_add2"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s ERROR_ON_UNDEFINED_SYMBOLS=0 16 | warning: undefined symbol: writeout (referenced by top-level compiled C/C++ code) 17 | cat cfile.wasm | base64 > cfile.wasm.b64 18 | gcc -o wasmtemplate wasmtemplate.c 19 | ./wasmtemplate template.ht cfile.wasm.b64 > c-test.html 20 | ``` 21 | -------------------------------------------------------------------------------- /c-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 144 | 145 | 146 |
147 |
148 |
This is an example of a fully integrated wasm page. It shows how you can run wasm without fetch() or anything so it loads super quick even over connections with really high latency, or you can run it from your hard drive just by double clicking on it. Check out the project here: https://github.com/cnlohr/wasm_integrated.
149 | 150 | 151 |
152 |
153 | 154 |
155 |
156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /cfile.c: -------------------------------------------------------------------------------- 1 | //Function in Javascript Land 2 | extern void canvasClear(); 3 | extern void beginPath(); 4 | extern void tackSegment(int x1, int y1, int x2, int y2); 5 | extern void stroke(); 6 | extern void logNum(unsigned int x); 7 | extern void requestAnimationFrame(); 8 | extern void setTimeout(unsigned int); 9 | extern float sinf(float x); 10 | extern float cosf(float x); 11 | 12 | void start_unwind(void*); 13 | void stop_unwind(); 14 | void start_rewind(void*); 15 | void stop_rewind(); 16 | 17 | const unsigned int callStackSize = 4096; 18 | unsigned char callStack[callStackSize]; 19 | struct { 20 | void *beg; 21 | void *end; 22 | } callStruct = { 23 | callStack, 24 | &callStack[callStackSize] 25 | }; 26 | unsigned char sleepStack[callStackSize]; 27 | struct { 28 | void *beg; 29 | void *end; 30 | } sleepStruct = { 31 | sleepStack, 32 | &sleepStack[callStackSize] 33 | }; 34 | 35 | unsigned char sleeping0 = 0; 36 | void submitFrame() { 37 | if(!sleeping0) { 38 | sleeping0 = 1; 39 | start_unwind(&callStruct); 40 | } else { 41 | stop_rewind(); 42 | sleeping0 = 0; 43 | } 44 | } 45 | void animation() { 46 | int frame = 0; 47 | do { 48 | canvasClear(); 49 | beginPath(); 50 | for(int i = 0; i <= 62; i++) { 51 | int r1 = 120; 52 | int r2 = 120; 53 | int cx = 320; 54 | int cy = 240; 55 | float a1 = i / 10. + frame / 60.; 56 | float a2 = i / 10. + 1; 57 | tackSegment(cx+cosf(a1)*r1, cy+sinf(a1)*r1, cx+cosf(a2)*r2, cy+sinf(a2)*r2); 58 | } 59 | stroke(); 60 | submitFrame(); 61 | ++frame; 62 | } while(1); 63 | } 64 | void reenterAnimation() { 65 | start_rewind(&callStruct); 66 | animation(); 67 | stop_unwind(); 68 | requestAnimationFrame(); 69 | } 70 | void runAnimation() { 71 | animation(); 72 | stop_unwind(); 73 | requestAnimationFrame(); 74 | } 75 | 76 | unsigned char sleeping1 = 0; 77 | void timerSleep() { 78 | if(!sleeping1) { 79 | sleeping1 = 1; 80 | start_unwind(&sleepStruct); 81 | } else { 82 | stop_rewind(); 83 | sleeping1 = 0; 84 | } 85 | } 86 | void timerLoop() { 87 | unsigned int num = 0; 88 | do { 89 | logNum(++num); 90 | timerSleep(); 91 | } while(1); 92 | } 93 | void reenterTimer() { 94 | start_rewind(&sleepStruct); 95 | timerLoop(); 96 | stop_unwind(); 97 | setTimeout(1000); 98 | } 99 | void runTimer() { 100 | timerLoop(); 101 | stop_unwind(); 102 | setTimeout(1000); 103 | } 104 | -------------------------------------------------------------------------------- /template.ht: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 59 | 60 | 61 |
62 |
63 |
This is an example of a fully integrated wasm page. It shows how you can run wasm without fetch() or anything so it loads super quick even over connections with really high latency, or you can run it from your hard drive just by double clicking on it. Check out the project here: https://github.com/cnlohr/wasm_integrated.
64 | 65 | 66 |
67 |
68 | 69 |
70 |
71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /wasmtemplate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main( int argc, char ** argv ) 6 | { 7 | if( argc != 3 ) 8 | { 9 | fprintf( stderr, "Usage: detemplate template.ht datafile.b64\n" ); 10 | return -5; 11 | } 12 | FILE * ht = fopen( argv[1], "rb" ); 13 | FILE * df = fopen( argv[2], "rb" ); 14 | if( !ht ) 15 | { 16 | fprintf( stderr, "Error: cannot open template file \"%s\"\n", argv[1] ); 17 | exit( -5 ); 18 | } 19 | if( !df ) 20 | { 21 | fprintf( stderr, "Error: cannot open data file \"%s\"\n", argv[2] ); 22 | exit( -6 ); 23 | } 24 | 25 | int maxlinelen = 80; 26 | char * line = malloc(maxlinelen); 27 | int lineptr = 0; 28 | int c; 29 | while( ( c = fgetc(ht) ) != EOF ) 30 | { 31 | if( c == '\n' ) 32 | { 33 | if( strcmp( line, "%WASMBLOB%" ) == 0 ) 34 | { 35 | while( ( c = fgetc(df) )!= EOF ) 36 | { 37 | if( c == '\n' ) 38 | printf( "\\\n\t\t" ); 39 | else 40 | putchar( c ); 41 | } 42 | } 43 | else 44 | { 45 | puts( line ); 46 | } 47 | lineptr = 0; 48 | line[lineptr] = 0; 49 | } 50 | else 51 | { 52 | line[lineptr++] = c; 53 | if( lineptr >= maxlinelen ) 54 | { 55 | maxlinelen *= 2; 56 | line = realloc( line, maxlinelen ); 57 | } 58 | line[lineptr] = 0; 59 | } 60 | } 61 | } 62 | --------------------------------------------------------------------------------