Emscripten рдХреЗ рдмрд┐рдирд╛ WebAssembly рдореЗрдВ рд╕реА рдХрд╛ рд╕рдВрдХрд▓рди

рд╕рдВрдХрд▓рдХ Emscripten рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЖрдк рд╕рднреА рд╕реАрдЯреА рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рдХреЗрд╡рд▓ рдЗрд╕реЗ рдЫреЛрдбрд╝ рджреЗрдВ?

Emscripten рдХреЛ WebAssembly рдореЗрдВ C / C ++ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╕рдВрдХрд▓рдХ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИред Emscripten рдХрд╛ рд▓рдХреНрд╖реНрдп рдЖрдкрдХреЗ C / C ++ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрджрд▓рдирд╛ рд╣реИ рдФрд░ рдХреЛрдб рдХреЛ рд╡реЗрдм рдкрд░ рдЪрд▓рд╛рдирд╛ рд╣реИ рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рд╡реЗрдм рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рдЗрд╕рдХреЗ рд▓рд┐рдП, Emscripten рдкреВрд░реЗ POSIX рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо fopen () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ Emscripten рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдЗрдореНрдпреВрд▓реЗрд╢рди рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ред рдпрджрд┐ OpenGL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ Emscripten WebGL рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд C- рд╕рдВрдЧрдд GL рд╕рдВрджрд░реНрдн рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ред рдпрд╣ рдмрд╣реБрдд рдХрд╛рдо рд╣реИ, рдФрд░ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рдЬрд┐рдиреНрд╣реЗрдВ рдЕрдВрддрд┐рдо рдкреИрдХреЗрдЬ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЖрдк рдЗрд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ ...?

Emscripten рдЯреВрд▓рдХрд┐рдЯ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдХрд▓рдХ LLVM рд╣реИред рдпрд╣ рд╡рд╣ рд╣реИ рдЬреЛ WebAssembly рдмрд╛рдпрдЯреЗрдХреЛрдб рдореЗрдВ рд╕реА рдХреЛрдб рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг, рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзреБрдирд┐рдХ рдореЙрдбреНрдпреВрд▓рд░ рдврд╛рдВрдЪрд╛ рд╣реИред LLVM рдЗрд╕ рдЕрд░реНрде рдореЗрдВ рдореЙрдбреНрдпреВрд▓рд░ рд╣реИ рдХрд┐ рдпрд╣ рдХрднреА рднреА рдорд╢реАрди рдХреЛрдб рдореЗрдВ рд╕реАрдзреЗ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдлреНрд░рдВрдЯ-рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ (рдЖрдИрдЖрд░) рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдордзреНрдпрд╡рд░реНрддреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрд▓рдПрд▓рд╡реАрдПрдо рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдирд╛рдо рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдирд╛рдо рд╣реИред

рдмреИрдХрдПрдВрдб рдХрдВрдкрд╛рдЗрд▓рд░ IR рдХреЛ рд╣реЛрд╕реНрдЯ рдорд╢реАрди рдХреЛрдб рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рд╕рдЦреНрдд рдЕрд▓рдЧрд╛рд╡ рдХрд╛ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рдирдП рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдирдП рд╕рдВрдХрд▓рдХ рдХреЗ "рд╕рд░рд▓" рдЬреЛрдбрд╝ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдЕрд░реНрде рдореЗрдВ, WebAssembly рдПрд▓рдПрд▓рд╡реАрдПрдо рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрдИ рд╕рдВрдХрд▓рди рд▓рдХреНрд╖реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдФрд░ рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рд╕рдХреНрд░рд┐рдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред LLVM 8 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, WebAssembly рд╕рдВрдХрд▓рди рд▓рдХреНрд╖реНрдп рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реИред

MacOS рдкрд░, рдЖрдк рд╣реЛрдордмреНрд░реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ LLVM рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

$ brew install llvm $ brew link --force llvm 

WebAssembly рд╕рдорд░реНрдерди рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:

 $ llc --version LLVM (http://llvm.org/): LLVM version 8.0.0 Optimized build. Default target: x86_64-apple-darwin18.5.0 Host CPU: skylake Registered Targets: # тАж,  тАж systemz - SystemZ thumb - Thumb thumbeb - Thumb (big endian) wasm32 - WebAssembly 32-bit # ! ! ! wasm64 - WebAssembly 64-bit x86 - 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 xcore - XCore 

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рд╣рдо рддреИрдпрд╛рд░ рд╣реИрдВ!

C рд╣рд╛рд░реНрдб рд╕рдВрдХрд▓рди рдХрд╛ рд╕рдВрдХрд▓рди


рдиреЛрдЯ: рдпрд╣рд╛рдВ рдХреБрдЫ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп RAW WebAssembly рдкреНрд░рд╛рд░реВрдк рд╣реИрдВред рдЕрдЧрд░ рдЖрдкрдХреЛ рд╕рдордЭрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рддреЛ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд╣реИред WebAssembly рдХреЗ рдЕрдЪреНрдЫреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╕рдВрдкреВрд░реНрдг рдкрд╛рда рдХреА рд╕рдордЭ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдХреЙрд▓ рджреЗрдЦреЗрдВ ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдкрдврд╝рддреЗ рд░рд╣реЗрдВ! рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╢реБрджреНрдз Webassembly рдФрд░ рд╡рд╛рдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдЪрдп рд▓рд┐рдЦрд╛ рдерд╛: рдпреЗ рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореВрд▓ рдмрд╛рддреЗрдВ рд╣реИрдВред
рдЪреЗрддрд╛рд╡рдиреА: рдореИрдВ рдорд╛рдирдХ рд╕реЗ рдереЛрдбрд╝рд╛ рд╡рд┐рдЪрд▓рд┐рдд рд╣реЛрдКрдВрдЧрд╛ рдФрд░ рд╣рд░ рдХрджрдо (рдЬрд╣рд╛рдБ рддрдХ рд╕рдВрднрд╡ рд╣реЛ) рдорд╛рдирд╡-рдкрдардиреАрдп рд╕реНрд╡рд░реВрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдБрдЧрд╛ред рд╕реАрдорд╛рд╡рд░реНрддреА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдФрд░ рд╡рд┐рдЪрд▓рд┐рдд рди рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрд╣реБрдд рд╕рд░рд▓ рд╣реЛрдЧрд╛:

 // Filename: add.c int add(int a, int b) { return a*a + b; } 

рдХреНрдпрд╛ рд╢рд╛рдирджрд╛рд░ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрд░рддрдм! рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдРрдб рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ (рдирд╣реАрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ)ред рдЗрд╕рд╕реЗ рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд: рдХрд╛рд░реНрдпрдХреНрд░рдо рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдБ рдХреЗ рдкреНрд░рдХрд╛рд░, рдХреЗрд╡рд▓ 'int'ред

C рдХреЛ рдЖрдВрддрд░рд┐рдХ LLVM рд╡реНрдпреВ рдореЗрдВ рдмрджрд▓рдирд╛


рдкрд╣рд▓рд╛ рдХрджрдо рд╣рдорд╛рд░реЗ рд╕реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ LLVM IR рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реИред рдпрд╣ clang рдлреНрд░рдВрдЯреЗрдВрдб рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд╛ рдХрд╛рд░реНрдп рд╣реИ, рдЬрд┐рд╕реЗ LLVM рдХреЗ рд╕рд╛рде рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 clang \ --target=wasm32 \ # Target WebAssembly -emit-llvm \ # Emit LLVM IR (instead of host machine code) -c \ # Only compile, no linking just yet -S \ # Emit human-readable assembly rather than binary add.c 

рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ LLVM IR рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рд╕рд╛рде add.ll рдорд┐рд▓рддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП рджрд┐рдЦрд╛рддрд╛ рд╣реВрдВ ред WebAssembly рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреНрд▓реИрдВрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдПрдХ рд╕реА рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдХреЗ рд╕рдВрдкрд░реНрдХ рдореЗрдВ рдХрднреА рдирд╣реАрдВ рдЖрдПрдВрдЧреЗред

 ; ModuleID = 'add.c' source_filename = "add.c" target datalayout = "em:ep:32:32-i64:64-n32:64-S128" target triple = "wasm32" ; Function Attrs: norecurse nounwind readnone define hidden i32 @add(i32, i32) local_unnamed_addr #0 { %3 = mul nsw i32 %0, %0 %4 = add nsw i32 %3, %1 ret i32 %4 } attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} !llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"} 

LLVM IR рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдФрд░ рдПрдиреЛрдЯреЗрд╢рди рд╕реЗ рднрд░рд╛ рд╣реИ, рдЬреЛ рдорд╢реАрди рдХреЛрдб рдмрдирд╛рддреЗ рд╕рдордп рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЕрдзрд┐рдХ рд╕реВрдЪрд┐рдд рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рдмрджрд▓ рджреЗрдВ


рдЕрдЧрд▓рд╛ рдЪрд░рдг рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП llc рдмреИрдХрдПрдВрдб рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИред

add.o рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╡реИрдз WebAssembly рдореЙрдбреНрдпреВрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░реА C рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рднреА рд╕рдВрдХрд▓рд┐рдд рдХреЛрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рдЖрдк рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдЖрд╡рд╢реНрдпрдХ рднрд╛рдЧреЛрдВ рдХреА рдХрдореА рд╣реЛрддреА рд╣реИред

рдЕрдЧрд░ рд╣рдо -filetype=obj рдЫреЛрдбрд╝ -filetype=obj рдХрдорд╛рдВрдб рдореЗрдВ рдЖ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ WebAssembly рдХреЗ рд▓рд┐рдП LLVM рдХреЛрдбрд╛рдВрддрд░рдХ рдорд┐рд▓реЗрдЧрд╛, рдЬреЛ рдПрдХ рдорд╛рдирд╡-рдкрдардиреАрдп рдкреНрд░рд╛рд░реВрдк рд╣реИ рдЬреЛ рдХреБрдЫ рд╣рдж рддрдХ рд╡рд╛рдЯ рдХреЗ рд╕рдорд╛рди рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдРрд╕реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП llvm-mc рдЯреВрд▓ рдЕрднреА рддрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рд╛рд░реВрдк рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдХреНрд╕рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рддрдереНрдп рдХреЗ рдмрд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░ рджреЗрддреЗ рд╣реИрдВред рдЗрди рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрдкрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред WebAssembly рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ wasm-objdump , WebAssembly рдмрд╛рдЗрдирд░реА рдЯреВрд▓рдХрд┐рдЯ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдпрд╛ рд╢реЙрд░реНрдЯ рдХреЗ рд▓рд┐рдП wabt рд╣реИред

 $ brew install wabt # in case you haven't $ wasm-objdump -x add.o add.o: file format wasm 0x1 Section Details: Type[1]: - type[0] (i32, i32) -> i32 Import[3]: - memory[0] pages: initial=0 <- env.__linear_memory - table[0] elem_type=funcref init=0 max=0 <- env.__indirect_function_table - global[0] i32 mutable=1 <- env.__stack_pointer Function[1]: - func[0] sig=0 <add> Code[1]: - func[0] size=75 <add> Custom: - name: "linking" - symbol table [count=2] - 0: F <add> func=0 binding=global vis=hidden - 1: G <env.__stack_pointer> global=0 undefined binding=global vis=default Custom: - name: "reloc.CODE" - relocations for section: 3 (Code) [1] R_WASM_GLOBAL_INDEX_LEB offset=0x000006(file=0x000080) symbol=1 <env.__stack_pointer> 

рдЖрдЙрдЯрдкреБрдЯ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдРрдб () рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╕реНрдЯрдо рдЕрдиреБрднрд╛рдЧ рднреА рд╣реИрдВ рдФрд░, рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ, рдХрдИ рдЖрдпрд╛рдд рд╣реИрдВред рд▓рд┐рдВрдХ рдХрд░рдиреЗ рдХреЗ рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ , рдХрд╕реНрдЯрдо рдЕрдиреБрднрд╛рдЧреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд▓рд┐рдВрдХрд░ (рд▓рд┐рдВрдХрд░) рдЖрдпрд╛рдд рд╕реЗ рдирд┐рдкрдЯреЗрдВрдЧреЗред

рд╡реНрдпрд╡рд╕реНрдерд╛


рдкрд░рдВрдкрд░рд╛рдЧрдд рд░реВрдк рд╕реЗ, рд▓рд┐рдВрдХрд░ рдХрд╛ рдХрд╛рд░реНрдп рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрдИ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рд╣реИред LLVM рд▓рд┐рдВрдХрд░ рдХреЛ lld рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЯрд╛рд░рдЧреЗрдЯ рд╕рд┐рдорд┐рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред WebAssembly рдХреЗ рд▓рд┐рдП, рдпрд╣ wasm-ld ред

 wasm-ld \ --no-entry \ # We don't have an entry function --export-all \ # Export everything (for now) -o add.wasm \ add.o 

рдкрд░рд┐рдгрд╛рдо рдЖрдХрд╛рд░ рдореЗрдВ 262 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдПрдХ WebAssembly рдореЙрдбреНрдпреВрд▓ рд╣реИред

рд▓рд╛рдВрдЪ


рдмреЗрд╢рдХ, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рджреЗрдЦрдирд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреА рддрд░рд╣ , рдЖрдк рдЗрд╕ WebAssembly рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓реЛрдб рдФрд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдореНрдмреЗрдбреЗрдб рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 <!DOCTYPE html> <script type="module"> async function init() { const { instance } = await WebAssembly.instantiateStreaming( fetch("./add.wasm") ); console.log(instance.exports.add(4, 1)); } init(); </script> 

рдпрджрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рддреЛ рдЖрдк DevTool рдХрдВрд╕реЛрд▓ рдореЗрдВ 17 рдирдВрдмрд░ рджреЗрдЦреЗрдВрдЧреЗред рд╣рдордиреЗ Emscripten рдХреЛ рдЫреВрдиреЗ рдХреЗ рдмрд┐рдирд╛ C рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ WebAssembly рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ WebAssembly рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдФрд░ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдирд╣реАрдВ рд╣реИред

рд╕рдВрдХрд▓рди C рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рд╣реИ


WebAssembly рдореЗрдВ рд╕реА рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдХрдИ рдХрджрдо рдЙрдард╛рдП рд╣реИрдВред рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рд╢реИрдХреНрд╖рд┐рдХ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд╕рднреА рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЬрд╛рдВрдЪ рдХреАред рдЖрдЗрдП рдорд╛рдирд╡-рдкрдврд╝рдиреЗ рдпреЛрдЧреНрдп рдордзреНрдпрд╡рд░реНрддреА рд╕реНрд╡рд░реВрдкреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ рдФрд░ рддреБрд░рдВрдд рд╕реА рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рд╕реНрд╡рд┐рд╕ рд╕реЗрдирд╛ рдХреЗ рдЪрд╛рдХреВ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░реЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:

 clang \ --target=wasm32 \ -nostdlib \ # Don't try and link against a standard library -Wl,--no-entry \ # Flags passed to the linker -Wl,--export-all \ -o add.wasm \ add.c 

рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдПрдХ рд╣реА .wasm рдлрд╝рд╛рдЗрд▓ .wasm рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рдеред

рдЕрдиреБрдХреВрд▓рди


Wasm2wat рдЪрд▓рд╛рдХрд░ рд╣рдорд╛рд░реЗ WebAssembly рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╡рд╛рдЯ рдкрд░ рдПрдХ рдирдЬрд╝рд░ wasm2wat :

 (module (type (;0;) (func)) (type (;1;) (func (param i32 i32) (result i32))) (func $__wasm_call_ctors (type 0)) (func $add (type 1) (param i32 i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32) global.get 0 local.set 2 i32.const 16 local.set 3 local.get 2 local.get 3 i32.sub local.set 4 local.get 4 local.get 0 i32.store offset=12 local.get 4 local.get 1 i32.store offset=8 local.get 4 i32.load offset=12 local.set 5 local.get 4 i32.load offset=12 local.set 6 local.get 5 local.get 6 i32.mul local.set 7 local.get 4 i32.load offset=8 local.set 8 local.get 7 local.get 8 i32.add local.set 9 local.get 9 return) (table (;0;) 1 1 anyfunc) (memory (;0;) 2) (global (;0;) (mut i32) (i32.const 66560)) (global (;1;) i32 (i32.const 66560)) (global (;2;) i32 (i32.const 1024)) (global (;3;) i32 (i32.const 1024)) (export "memory" (memory 0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__heap_base" (global 1)) (export "__data_end" (global 2)) (export "__dso_handle" (global 3)) (export "add" (func $add))) 

рд╡рд╛рд╣, рдХреНрдпрд╛ рдмрдврд╝рд┐рдпрд╛ рдХреЛрдб рд╣реИред рдореЗрд░реЗ рдЖрд╢реНрдЪрд░реНрдп рдХреЗ рд▓рд┐рдП, рдореЙрдбреНрдпреВрд▓ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ i32.load рдФрд░ i32.store рд╕реЗ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ), рдЖрда рд╕реНрдерд╛рдиреАрдп рдФрд░ рдХрдИ рдЕрдиреНрдп рд╡реИрд░рд┐рдПрдмрд▓ред рд╕рдВрднрд╡рддрдГ, рдЖрдк рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╕рдВрд╕реНрдХрд░рдг рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЗрддрдирд╛ рдмрдбрд╝рд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдХреЛрдИ рдЕрдиреБрдХреВрд▓рди рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЪрд▓реЛ рдЗрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ:

 clang \ --target=wasm32 \ + -O3 \ # Agressive optimizations + -flto \ # Add metadata for link-time optimizations -nostdlib \ -Wl,--no-entry \ -Wl,--export-all \ + -Wl,--lto-O3 \ # Aggressive link-time optimizations -o add.wasm \ add.c 

рдзреНрдпрд╛рди рджреЗрдВ: рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ, рд▓реЗрдЖрдЙрдЯ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди (LTO) рд╕реЗ рдХреЛрдИ рд▓рд╛рдн рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреА рд░рдЪрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ, рдПрд▓рдЯреАрдУ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред
рдЗрди рдЖрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж .wasm рдлрд╝рд╛рдЗрд▓ 262 рд╕реЗ рдШрдЯрдХрд░ 197 рдмрд╛рдЗрдЯреНрд╕ рд╣реЛ рдЧрдИ рдФрд░ рд╡рд╛рдЯ рднреА рдмрд╣реБрдд рд╕рд░рд▓ рд╣реЛ рдЧрдпрд╛:

 (module (type (;0;) (func)) (type (;1;) (func (param i32 i32) (result i32))) (func $__wasm_call_ctors (type 0)) (func $add (type 1) (param i32 i32) (result i32) local.get 0 local.get 0 i32.mul local.get 1 i32.add) (table (;0;) 1 1 anyfunc) (memory (;0;) 2) (global (;0;) (mut i32) (i32.const 66560)) (global (;1;) i32 (i32.const 66560)) (global (;2;) i32 (i32.const 1024)) (global (;3;) i32 (i32.const 1024)) (export "memory" (memory 0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__heap_base" (global 1)) (export "__data_end" (global 2)) (export "__dso_handle" (global 3)) (export "add" (func $add))) 

рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдмреБрд▓рд╛рдУ


рдорд╛рдирдХ libc рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдмрд┐рдирд╛ C рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрд╕рднреНрдп рд▓рдЧрддрд╛ рд╣реИред рдЗрд╕реЗ рдЬреЛрдбрд╝рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдИрдорд╛рдирджрд╛рд░ рд░рд╣реВрдВрдЧрд╛: рдпрд╣ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рд╕реАрдзреЗ рд▓реЗрдЦ рдореЗрдВ рдХрд┐рд╕реА рднреА libc рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЖрд╣реНрд╡рд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ ред рдХрдИ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ glibc , musl рдФрд░ dietlibc ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ POSIX рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВ, рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реЗрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХрд░реНрдиреЗрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЗрди POSIX рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд╕рдВрднрд╡рддрдГ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред рдпрд╣ рдПрдХ рдореБрд╢реНрдХрд┐рд▓ рдХрд╛рдо рд╣реИ рдФрд░ рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдВ рдирд╣реАрдВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдЕрдЪреНрдЫреА рдЦрдмрд░ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдПрдореНрд╕рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реИ ред

рдмреЗрд╢рдХ, рд╕рднреА libc рдлрд╝рдВрдХреНрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред strlen() , sin() рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ memset() рдЬреИрд╕реЗ рдХрд╛рд░реНрдп рд╕рд░рд▓ рд╕реА рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЖрдк рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдХреБрдЫ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдЙрдирдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛ / рдкреЗрд╕реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЧрддрд┐рд╢реАрд▓ рд╕реНрдореГрддрд┐


Libc рдХреЗ рдмрд┐рдирд╛, C рдореМрд▓рд┐рдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдЬреИрд╕реЗ malloc() рдФрд░ free() рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВред рдЧреИрд░-рдЕрдиреБрдХреВрд▓рд┐рдд рд╡рд╛рдЯ рдореЗрдВ, рд╣рдордиреЗ рджреЗрдЦрд╛ рдХрд┐ рд╕рдВрдХрд▓рдХ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдореЗрдореЛрд░реА рдХреЛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдиреБрдХрд╕рд╛рди рдкрд╣реБрдБрдЪрд╛рдП рдмрд┐рдирд╛, рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВред рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдореЛрд░реА рдореЙрдбрд▓


WebAssembly рдореЗрдореЛрд░реА рд╕реЗрдЧрдореЗрдВрдЯреЗрд╢рди рд╡рд┐рдзрд┐ рдЕрдиреБрднрд╡реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд░реНрд╕ рдХреЛ рдереЛрдбрд╝рд╛ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░реЗрдЧреАред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, WebAssembly рдореЗрдВ, рдПрдХ рд╢реВрдиреНрдп рдкрддрд╛ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдХреНрд╕рд░ рдЗрд╕реЗ рдЕрднреА рднреА рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рджреВрд╕рд░реЗ, рд╕реНрдЯреИрдХ рдкрд╣рд▓реЗ рдЖрддрд╛ рд╣реИ рдФрд░ рдиреАрдЪреЗ (рдкрддреЗ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдмрдврд╝рддрд╛ рд╣реИ, рдФрд░ рдвреЗрд░ рдмрд╛рдж рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ рдФрд░ рдмрдврд╝рддрд╛ рд╣реИред рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рд░рдирд╡реЗ рдкрд░ WebAssembly рдХреА рдореЗрдореЛрд░реА рдмрдврд╝ рд╕рдХрддреА рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╕реНрдЯреИрдХ рдпрд╛ рд╣реАрдк рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирд┐рд╢реНрдЪрд┐рдд рдЕрдВрдд рдирд╣реАрдВ рд╣реИред

рдпрд╣рд╛рдБ wasm-ld рд▓реЗрдЖрдЙрдЯ рд╣реИ:



рдвреЗрд░ рдиреАрдЪреЗ рдмрдврд╝рддрд╛ рд╣реИ, рдФрд░ рдвреЗрд░ рдмрдврд╝рддрд╛ рд╣реИред рд╕реНрдЯреИрдХ __data_end рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдвреЗрд░ __heap_base ред рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдЯреИрдХ рдХреЛ рдкрд╣рд▓реЗ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рд╣реИ, рдЕрд░реНрдерд╛рддреН __heap_base рдорд╛рдЗрдирд╕ __data_end

рдпрджрд┐ рд╣рдо рд╡рд╛рдкрд╕ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд╡рд╛рдЯ рдореЗрдВ __heap_base рд╕реЗрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпреЗ рдорд╛рди рдорд┐рд▓рддреЗ рд╣реИрдВ: __heap_base рд╕реЗрдЯ рд╣реИ, рдФрд░ __data_end 1024 рдкрд░ рд╕реЗрдЯ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕реНрдЯреИрдХ рдЕрдзрд┐рдХрддрдо 64 KiB рддрдХ рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЬреНрдпрд╛рджрд╛ рдирд╣реАрдВ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, wasm-ld рдЖрдкрдХреЛ рдпрд╣ рдорд╛рди рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

 clang \ --target=wasm32 \ -O3 \ -flto \ -nostdlib \ -Wl,--no-entry \ -Wl,--export-all \ -Wl,--lto-O3 \ + -Wl,-z,stack-size=$[8 * 1024 * 1024] \ # Set maximum stack size to 8MiB -o add.wasm \ add.c 

рдПрд▓рд╛рдЯреЗрдЯрд░ рд╡рд┐рдзрд╛рдирд╕рднрд╛


рдвреЗрд░ рдХреНрд╖реЗрддреНрд░ рдХреЛ __heap_base рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ malloc() рдлрд╝рдВрдХреНрд╢рди рдЧрд╛рдпрдм рд╣реИ, рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЕрдЧрд▓реЗ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд╡рд╣рд╛рдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕рд╛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдореЗрдореЛрд░реА рднреНрд░рд╖реНрдЯрд╛рдЪрд╛рд░ рд╕реЗ рдбрд░рдиреЗ рдХреА рдХреЛрдИ рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдЯреИрдХ рджреВрд╕рд░реА рджрд┐рд╢рд╛ рдореЗрдВ рдмрдврд╝рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рднреА рдХреЗ рд▓рд┐рдП рдирд┐: рд╢реБрд▓реНрдХ рдПрдХ рдвреЗрд░ рдЬрд▓реНрджреА рд╕реЗ рднрд░рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдорддреМрд░ рдкрд░ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЧрддрд┐рд╢реАрд▓ рд╕реНрдореГрддрд┐ рдкреНрд░рдмрдВрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдХрд┐ рдореЙрд▓реЙрдХ () рдХрд╛ рдкреВрд░реНрдгрд░реВрдкреЗрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдЬреИрд╕реЗ рдХрд┐ рдбрдЧ рд▓реА рд╕реЗ рдореЙрд▓реЙрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди , рдЬрд┐рд╕реЗ рдПрдореНрд╕рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдЯреНрд░реЗрдб-рдСрдл рдХреЗ рд╕рд╛рде рдХрдИ рдФрд░ рдЫреЛрдЯреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВред

рд▓реЗрдХрд┐рди рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ malloc() рдХреНрдпреЛрдВ рдирд╣реАрдВ рд▓рд┐рдЦрд╛? рд╣рдо рдЗрддрдиреА рдЧрд╣рд░рд╛рдИ рд╕реЗ рдШрд┐рд░реЗ рд╣реБрдП рд╣реИрдВ рдХрд┐ рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред рд╕рдмрд╕реЗ рд╕рд░рд▓ рдореЗрдВ рд╕реЗ рдПрдХ рдПрдХ рдЯрдХреНрдХрд░ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рд╣реИ: рдпрд╣ рд╕реБрдкрд░рдлрд╛рд╕реНрдЯ рд╣реИ, рдмреЗрд╣рдж рдЫреЛрдЯрд╛ рдФрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИред рд▓реЗрдХрд┐рди рдПрдХ рдЦрд╛рдореА рд╣реИ: рдЖрдк рд╕реНрдореГрддрд┐ рдХреЛ рдореБрдХреНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рдРрд╕рд╛ рдПрд▓реЛрдХреЗрдЯрд░ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдмреЗрдХрд╛рд░ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдХреНрд╡реЙрд╢ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди , рдореИрдВ рдРрд╕реА рдХрдИ рдорд┐рд╕рд╛рд▓реЗрдВ рд▓реЗрдХрд░ рдЖрдпрд╛ , рдЬрд╣рд╛рдБ рдпрд╣ рдПрдХ рдмреЗрд╣рддрд░реАрди рд╡рд┐рдХрд▓реНрдк рд╣реЛрдЧрд╛ред рдПрдХ рдмрдореНрдкрд░ рдЖрд╡рдВрдЯрди рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрдкреНрд░рдпреБрдХреНрдд рдореЗрдореЛрд░реА рдХреЗ рд╢реБрд░реБрдЖрддреА рдкрддреЗ рдХреЛ рд╡реИрд╢реНрд╡рд┐рдХ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдореЛрд░реА рдХреЗ n рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдорд╛рд░реНрдХрд░ рдХреЛ n рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдкрд┐рдЫрд▓рд╛ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ:

 extern unsigned char __heap_base; unsigned int bump_pointer = &__heap_base; void* malloc(int n) { unsigned int r = bump_pointer; bump_pointer += n; return (void *)r; } void free(void* p) { // lol } 

рд╡рд╛рдЯ рд╕реЗ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ wasm-ld рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП wasm-ld , рддрд╛рдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ C рдХреЛрдб рд╕реЗ рд╕рд╛рдзрд╛рд░рдг рдЪрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХреЗрдВ рдпрджрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ extern рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рдЕрднреА рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ malloc() ... рд╕реА рдХреА рдкрд╛рдВрдЪ рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИред

рдиреЛрдЯ: рд╣рдорд╛рд░рд╛ рдмрдореНрдк рдПрд▓реЛрдХреЗрдЯрд░ рд╕реА рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ malloc() рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдВрд░реЗрдЦрдг рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП ...

рдЧрддрд┐рд╢реАрд▓ рд╕реНрдореГрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ


рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╝рдВрдХреНрд╢рди C рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдордирдорд╛рдиреЗ рдЖрдХрд╛рд░ рдХреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдпреЛрдЧ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рджреМрд░рд╛рди рд╕рд░рдгреА рдХрд╛ рдЖрдХрд╛рд░ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ:

 int sum(int a[], int len) { int sum = 0; for(int i = 0; i < len; i++) { sum += a[i]; } return sum; } 

рд░рд╛рд╢рд┐ () рдлрд╝рдВрдХреНрд╢рди, рдЙрдореНрдореАрдж рд╣реИ, рдмрд╣реБрдд рд╕реАрдзрд╛ рд╣реИред рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рд╡реЗрдмрдПрдПрд╕рдПрд╕рдПрдлрд╝рдЖрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рдгреА рдХреЛ рдХреИрд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП - рдЖрдЦрд┐рд░рдХрд╛рд░, рд╡реЗрдмрдПрд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗрд╡рд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рд╕рдордЭрддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рдореЗрдореЛрд░реА рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ malloc() рд╕реЗ malloc() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рд╡рд╣рд╛рдВ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдкрддрд╛ (рд╕рдВрдЦреНрдпрд╛!) рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рд╕рд░рдгреА рд╕реНрдерд┐рдд рд╣реИ:

 <!DOCTYPE html> <script type="module"> async function init() { const { instance } = await WebAssembly.instantiateStreaming( fetch("./add.wasm") ); const jsArray = [1, 2, 3, 4, 5]; // Allocate memory for 5 32-bit integers // and return get starting address. const cArrayPointer = instance.exports.malloc(jsArray.length * 4); // Turn that sequence of 32-bit integers // into a Uint32Array, starting at that address. const cArray = new Uint32Array( instance.exports.memory.buffer, cArrayPointer, jsArray.length ); // Copy the values from JS to C. cArray.set(jsArray); // Run the function, passing the starting address and length. console.log(instance.exports.sum(cArrayPointer, cArray.length)); } init(); </script> 

рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ DevTools рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЙрддреНрддрд░ 15 рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ 1 рд╕реЗ 5 рддрдХ рд╕рднреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдпреЛрдЧ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рддреЛ, рдЖрдк рдЕрдВрдд рддрдХ рдкрдврд╝реЗрдВред рдмрдзрд╛рдИ! рдлрд┐рд░, рдпрджрд┐ рдЖрдк рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рднрд╛рд░ рдорд╣рд╕реВрд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИред рд╕рднреА рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдЙрдиреНрд╣реЗрдВ рд╕рдордЭрдирд╛ рдПрдХ рдЕрдЪреНрдЫреЗ рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ рдФрд░ WebAssembly рдХреЗ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рднреА рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ ред рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдЙрди рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд░рд╛рд╣рдирд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдореНрд╕рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрди рдЬреИрд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд░рддреА рд╣реИред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдпрд╣ рд╕рдордЭ рджреЗрддрд╛ рд╣реИ рдХрд┐ WebAssembly рдХреЗ рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдореЙрдбреНрдпреВрд▓ рдХрд┐рддрдиреЗ рдЫреЛрдЯреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╕рд░рдгреА рдХреЗ рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕рдо рдореЙрдбреНрдпреВрд▓ рдХреЗрд╡рд▓ 230 рдмрд╛рдЗрдЯреНрд╕ рдЖрдХрд╛рд░ рдХрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдбрд╛рдпрдиреЗрдорд┐рдХ рдореЗрдореЛрд░реА рдПрд▓реЛрдХреЗрдЯрд░ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ ред Emscripten рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдкрд░ WebAssembly рдХреЛрдб рдХреЗ 100 рдмрд╛рдЗрдЯ рдФрд░ 11K JavaScript рд▓рд┐рдВрдХрд┐рдВрдЧ рдХреЛрдб рдХрд╛ рдЙрддреНрдкрд╛рджрди рд╣реЛрдЧрд╛ред рдЖрдкрдХреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╣реИрдВ рдЬрдм рдпрд╣ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИред

Source: https://habr.com/ru/post/hi454868/


All Articles