Binaryen, WebAssembly के लिए एक कंपाइलर और टूलचेन इंफ़्रास्ट्रक्चर लाइब्रेरी है. इसे C++ में लिखा गया है. इसका मकसद, WebAssembly में कंपाइल करने की प्रोसेस को आसान, तेज़, और असरदार बनाना है. इस पोस्ट में, ExampleScript नाम की सिंथेटिक टॉय लैंग्वेज के उदाहरण का इस्तेमाल करके, Binaryen.js API का इस्तेमाल करके JavaScript में WebAssembly मॉड्यूल लिखने का तरीका जानें. आपको मॉड्यूल बनाने, मॉड्यूल में फ़ंक्शन जोड़ने, और मॉड्यूल से फ़ंक्शन एक्सपोर्ट करने के बारे में बुनियादी जानकारी मिलेगी. इससे आपको WebAssembly में प्रोग्रामिंग लैंग्वेज को कंपाइल करने के पूरे प्रोसेस के बारे में जानकारी मिलेगी. इसके अलावा, आपको यह भी पता चलेगा कि Binaryen.js और wasm-opt
की मदद से, कमांड लाइन पर Wasm मॉड्यूल को कैसे ऑप्टिमाइज़ किया जा सकता है.
Binaryen के बारे में जानकारी
Binaryen में एक ही हेडर में, इस्तेमाल में आसान C API होता है. साथ ही, इसे JavaScript से भी इस्तेमाल किया जा सकता है. यह WebAssembly फ़ॉर्म में इनपुट स्वीकार करता है. हालांकि, यह उन कंपाइलर के लिए सामान्य कंट्रोल फ़्लो ग्राफ़ भी स्वीकार करता है जो इसे पसंद करते हैं.
इंटरमीडिएट रिप्रेजेंटेशन (आईआर), डेटा स्ट्रक्चर या कोड होता है. इसका इस्तेमाल कंपाइलर या वर्चुअल मशीन, सोर्स कोड को दिखाने के लिए करती है. Binaryen का इंटरनल आईआर, कॉम्पैक्ट डेटा स्ट्रक्चर का इस्तेमाल करता है. इसे पूरी तरह से पैरलल कोड जनरेशन और ऑप्टिमाइज़ेशन के लिए डिज़ाइन किया गया है. इसमें उपलब्ध सभी सीपीयू कोर का इस्तेमाल किया जाता है. Binaryen का IR, WebAssembly का सबसेट होने की वजह से WebAssembly में कंपाइल हो जाता है.
Binaryen के ऑप्टिमाइज़र में कई पास होते हैं. इनसे कोड के साइज़ और उसकी स्पीड को बेहतर बनाया जा सकता है. इन ऑप्टिमाइज़ेशन का मकसद, Binaryen को इतना बेहतर बनाना है कि इसे कंपाइलर बैकएंड के तौर पर इस्तेमाल किया जा सके. इसमें WebAssembly के लिए खास तौर पर किए गए ऑप्टिमाइज़ेशन शामिल हैं. सामान्य मकसद वाले कंपाइलर शायद ऐसा न करें. इसे Wasm को छोटा करने की प्रोसेस के तौर पर देखा जा सकता है.
Binaryen का इस्तेमाल करने वाले उपयोगकर्ता के तौर पर AssemblyScript
Binaryen का इस्तेमाल कई प्रोजेक्ट में किया जाता है. उदाहरण के लिए, AssemblyScript. यह Binaryen का इस्तेमाल करके, TypeScript जैसी भाषा से सीधे WebAssembly में कंपाइल करता है. AssemblyScript के प्लेग्राउंड में, उदाहरण आज़माएँ.
AssemblyScript इनपुट:
export function add(a: i32, b: i32): i32 {
return a + b;
}
Binaryen से जनरेट किया गया, टेक्स्ट के तौर पर WebAssembly कोड:
(module
(type $0 (func (param i32 i32) (result i32)))
(memory $0 0)
(export "add" (func $module/add))
(export "memory" (memory $0))
(func $module/add (param $0 i32) (param $1 i32) (result i32)
local.get $0
local.get $1
i32.add
)
)
Binaryen टूलचेन
Binaryen टूलचेन, JavaScript डेवलपर और कमांड लाइन का इस्तेमाल करने वाले लोगों के लिए कई काम के टूल उपलब्ध कराता है. इन टूल का सबसेट यहां दिया गया है. इसमें शामिल सभी टूल की पूरी सूची प्रोजेक्ट की README
फ़ाइल में उपलब्ध है.
binaryen.js
: यह एक स्टैंडअलोन JavaScript लाइब्रेरी है. यह Wasm मॉड्यूल बनाने और उन्हें ऑप्टिमाइज़ करने के लिए, Binaryen के तरीकों को दिखाती है. बिल्ड के लिए, npm पर binaryen.js देखें. इसके अलावा, इसे सीधे GitHub या unpkg से डाउनलोड करें.wasm-opt
: यह कमांड लाइन टूल है, जो WebAssembly को लोड करता है और उस पर Binaryen IR पास चलाता है.wasm-as
औरwasm-dis
: ये कमांड लाइन टूल हैं. इनका इस्तेमाल WebAssembly को असेंबल और डिसअसेंबल करने के लिए किया जाता है.wasm-ctor-eval
: यह एक कमांड लाइन टूल है. यह कंपाइल टाइम पर फ़ंक्शन (या फ़ंक्शन के कुछ हिस्सों) को एक्ज़ीक्यूट कर सकता है.wasm-metadce
: यह कमांड लाइन टूल, Wasm फ़ाइलों के कुछ हिस्सों को इस तरह से हटाता है कि मॉड्यूल के इस्तेमाल के तरीके पर कोई असर न पड़े.wasm-merge
: यह एक कमांड लाइन टूल है. यह कई Wasm फ़ाइलों को एक फ़ाइल में मर्ज करता है. साथ ही, इंपोर्ट किए गए फ़ंक्शन को एक्सपोर्ट किए गए फ़ंक्शन से कनेक्ट करता है. यह JavaScript के लिए बंडलर की तरह काम करता है, लेकिन यह Wasm के लिए होता है.
WebAssembly में कंपाइल करना
किसी एक भाषा को दूसरी भाषा में कंपाइल करने के लिए, आम तौर पर कई चरणों को पूरा करना पड़ता है. इनमें से सबसे अहम चरण यहां दिए गए हैं:
- लेक्सिकल विश्लेषण: सोर्स कोड को टोकन में तोड़ना.
- सिंटैक्स का विश्लेषण: ऐब्स्ट्रैक्ट सिंटैक्स ट्री बनाएं.
- सिमेंटिक विश्लेषण: गड़बड़ियों की जांच करें और भाषा के नियमों को लागू करें.
- इंटरमीडिएट कोड जनरेट करना: ज़्यादा ऐब्स्ट्रैक्ट कोड जनरेट करना.
- कोड जनरेट करना: टारगेट की भाषा में अनुवाद करें.
- टारगेट के हिसाब से कोड ऑप्टिमाइज़ करना: टारगेट के हिसाब से ऑप्टिमाइज़ करें.
Unix में, कंपाइल करने के लिए अक्सर इस्तेमाल किए जाने वाले टूल ये हैं:
lex
और
yacc
:
lex
(लेक्सिकल ऐनलाइज़र जनरेटर):lex
एक ऐसा टूल है जो लेक्सिकल ऐनलाइज़र जनरेट करता है. इन्हें लेक्सर या स्कैनर भी कहा जाता है. यह रेगुलर एक्सप्रेशन और उनसे जुड़ी कार्रवाइयों के सेट को इनपुट के तौर पर लेता है. साथ ही, यह लेक्सिकल ऐनलाइज़र के लिए कोड जनरेट करता है. यह इनपुट सोर्स कोड में पैटर्न की पहचान करता है.yacc
(Yet Another Compiler Compiler):yacc
एक ऐसा टूल है जो सिंटैक्स का विश्लेषण करने के लिए पार्सर जनरेट करता है. यह किसी प्रोग्रामिंग भाषा के व्याकरण के बारे में जानकारी को इनपुट के तौर पर लेता है और पार्सर के लिए कोड जनरेट करता है. पार्सर आम तौर पर ऐब्स्ट्रैक्ट सिंटैक्स ट्री (एएसटी) बनाते हैं. ये एएसटी, सोर्स कोड के हैरारिकल स्ट्रक्चर को दिखाते हैं.
हल किया गया उदाहरण
इस पोस्ट के दायरे को देखते हुए, किसी प्रोग्रामिंग भाषा के बारे में पूरी जानकारी देना मुमकिन नहीं है. इसलिए, इसे आसान बनाने के लिए, एक बहुत ही सीमित और बेकार सिंथेटिक प्रोग्रामिंग भाषा ExampleScript के बारे में जानें. यह भाषा, सामान्य कार्रवाइयों को उदाहरणों के ज़रिए दिखाती है.
add()
फ़ंक्शन लिखने के लिए, आपको जोड़ के किसी भी उदाहरण को कोड करना होगा. जैसे,2 + 3
.multiply()
फ़ंक्शन लिखने के लिए, उदाहरण के लिए,multiply()
लिखें.6 * 12
पहले से दी गई चेतावनी के मुताबिक, यह पूरी तरह से बेकार है. हालांकि, यह इतना आसान है कि इसका लेक्सिकल
ऐनललाइज़र एक रेगुलर एक्सप्रेशन हो सकता है: /\d+\s*[\+\-\*\/]\s*\d+\s*/
.
इसके बाद, एक पार्सर होना चाहिए. दरअसल, नाम वाले कैप्चरिंग ग्रुप के साथ रेगुलर एक्सप्रेशन का इस्तेमाल करके, ऐब्स्ट्रैक्ट सिंटैक्स ट्री का बहुत आसान वर्शन बनाया जा सकता है:
/(?<first_operand>\d+)\s*(?<operator>[\+\-\*\/])\s*(?<second_operand>\d+)/
.
ExampleScript की हर कमांड एक लाइन में होती है, ताकि पार्सर कोड को लाइन के हिसाब से प्रोसेस कर सके. इसके लिए, वह नई लाइन के वर्णों को अलग करता है. यह जानकारी, बुलेट लिस्ट में दिए गए पहले तीन चरणों की जांच करने के लिए काफ़ी है. ये चरण हैं: लेक्सिकल विश्लेषण, सिंटैक्स विश्लेषण, और सिमेंटिक विश्लेषण. इन चरणों के लिए कोड, यहां दिया गया है.
export default class Parser {
parse(input) {
input = input.split(/\n/);
if (!input.every((line) => /\d+\s*[\+\-\*\/]\s*\d+\s*/gm.test(line))) {
throw new Error('Parse error');
}
return input.map((line) => {
const { groups } =
/(?<first_operand>\d+)\s*(?<operator>[\+\-\*\/])\s*(?<second_operand>\d+)/gm.exec(
line,
);
return {
firstOperand: Number(groups.first_operand),
operator: groups.operator,
secondOperand: Number(groups.second_operand),
};
});
}
}
इंटरमीडिएट कोड जनरेट करना
अब ExampleScript प्रोग्राम को ऐब्स्ट्रैक्ट सिंटैक्स ट्री के तौर पर दिखाया जा सकता है. हालांकि, यह काफ़ी आसान है. अगला चरण, ऐब्स्ट्रैक्ट इंटरमीडिएट रिप्रेजेंटेशन बनाना है. पहला चरण है, Binaryen में नया मॉड्यूल बनाना:
const module = new binaryen.Module();
अब्सट्रैक्ट सिंटैक्स ट्री की हर लाइन में तीन चीज़ें होती हैं: firstOperand
, operator
, और secondOperand
. ExampleScript में मौजूद चार ऑपरेटर, यानी +
, -
, *
, /
के लिए, मॉड्यूल में एक नया फ़ंक्शन जोड़ना होगा. इसके लिए, Binaryen के Module#addFunction()
तरीके का इस्तेमाल करें. Module#addFunction()
तरीकों के पैरामीटर यहां दिए गए हैं:
name
:string
, फ़ंक्शन के नाम को दिखाता है.functionType
:Signature
, फ़ंक्शन के सिग्नेचर को दिखाता है.varTypes
:Type[]
से, दी गई क्रम में अन्य भाषाओं के बारे में पता चलता है.body
: एकExpression
, फ़ंक्शन का कॉन्टेंट.
यहां कुछ और जानकारी दी गई है. Binaryen के दस्तावेज़ से आपको इस बारे में ज़्यादा जानकारी मिल सकती है. हालांकि, आखिर में ExampleScript के +
ऑपरेटर के लिए, आपको Module#i32.add()
तरीके पर जाना होगा. यह पूर्णांकों पर की जाने वाली कई कार्रवाइयों में से एक है.
जोड़ने के लिए दो ऑपरेंड की ज़रूरत होती है. पहला और दूसरा समैंड. फ़ंक्शन को कॉल करने के लिए, इसे Module#addFunctionExport()
के साथ एक्सपोर्ट करना ज़रूरी है.
module.addFunction(
'add', // name: string
binaryen.createType([binaryen.i32, binaryen.i32]), // params: Type
binaryen.i32, // results: Type
[binaryen.i32], // vars: Type[]
// body: ExpressionRef
module.block(null, [
module.local.set(
2,
module.i32.add(
module.local.get(0, binaryen.i32),
module.local.get(1, binaryen.i32),
),
),
module.return(module.local.get(2, binaryen.i32)),
]),
);
module.addFunctionExport('add', 'add');
ऐब्स्ट्रैक्ट सिंटैक्स ट्री को प्रोसेस करने के बाद, मॉड्यूल में चार तरीके होते हैं. इनमें से तीन पूर्णांकों के साथ काम करते हैं. जैसे, add()
पर आधारित Module#i32.add()
, subtract()
पर आधारित Module#i32.sub()
, multiply()
पर आधारित Module#i32.mul()
, और आउटलायर divide()
पर आधारित Module#f64.div()
. ऐसा इसलिए, क्योंकि ExampleScript फ़्लोटिंग पॉइंट के नतीजों के साथ भी काम करता है.
for (const line of parsed) {
const { firstOperand, operator, secondOperand } = line;
if (operator === '+') {
module.addFunction(
'add', // name: string
binaryen.createType([binaryen.i32, binaryen.i32]), // params: Type
binaryen.i32, // results: Type
[binaryen.i32], // vars: Type[]
// body: ExpressionRef
module.block(null, [
module.local.set(
2,
module.i32.add(
module.local.get(0, binaryen.i32),
module.local.get(1, binaryen.i32)
)
),
module.return(module.local.get(2, binaryen.i32)),
])
);
module.addFunctionExport('add', 'add');
} else if (operator === '-') {
module.subtractFunction(
// Skipped for brevity.
)
} else if (operator === '*') {
// Skipped for brevity.
}
// And so on for all other operators, namely `-`, `*`, and `/`.
अगर आपको असल कोड बेस से डील करना है, तो कभी-कभी ऐसा कोड दिखेगा जिसे कभी कॉल नहीं किया जाता. ExampleScript के Wasm में कंपाइल होने के मौजूदा उदाहरण में, डेड कोड (जिसे बाद के चरण में ऑप्टिमाइज़ किया जाएगा और हटा दिया जाएगा) को आर्टिफ़िशियली तौर पर शामिल करने के लिए, एक्सपोर्ट न किए गए फ़ंक्शन को जोड़ा जाता है.
// This function is added, but not exported,
// so it's effectively dead code.
module.addFunction(
'deadcode', // name: string
binaryen.createType([binaryen.i32, binaryen.i32]), // params: Type
binaryen.i32, // results: Type
[binaryen.i32], // vars: Type[]
// body: ExpressionRef
module.block(null, [
module.local.set(
2,
module.i32.div_u(
module.local.get(0, binaryen.i32),
module.local.get(1, binaryen.i32),
),
),
module.return(module.local.get(2, binaryen.i32)),
]),
);
कंपाइलर अब लगभग तैयार है. यह ज़रूरी नहीं है, लेकिन Module#validate()
तरीके से मॉड्यूल की पुष्टि करना एक अच्छा तरीका है.
if (!module.validate()) {
throw new Error('Validation error');
}
Wasm कोड पाना
Wasm कोड पाने के लिए, Binaryen में दो तरीके उपलब्ध हैं. पहला तरीका, S-एक्सप्रेशन के तौर पर .wat
फ़ाइल में टेक्स्ट के तौर पर दिखाया गया कोड पाने का है. यह ऐसा फ़ॉर्मैट होता है जिसे कोई भी व्यक्ति आसानी से पढ़ सकता है. दूसरा तरीका, .wasm
फ़ाइल के तौर पर बाइनरी कोड पाने का है. यह फ़ाइल सीधे ब्राउज़र में चल सकती है. बाइनरी कोड को सीधे ब्राउज़र में चलाया जा सकता है. यह देखने के लिए कि एक्सपोर्ट की सुविधा काम कर रही है या नहीं, एक्सपोर्ट किए गए डेटा को लॉग किया जा सकता है.
const textData = module.emitText();
console.log(textData);
const wasmData = module.emitBinary();
const compiled = new WebAssembly.Module(wasmData);
const instance = new WebAssembly.Instance(compiled, {});
console.log('Wasm exports:\n', instance.exports);
नीचे, ExampleScript प्रोग्राम के लिए टेक्स्ट के तौर पर पूरी जानकारी दी गई है. इसमें चारों कार्रवाइयों की जानकारी शामिल है. ध्यान दें कि डेड कोड अब भी मौजूद है. हालांकि, WebAssembly.Module.exports()
के स्क्रीनशॉट के मुताबिक, इसे दिखाया नहीं गया है.
(module
(type $0 (func (param i32 i32) (result i32)))
(type $1 (func (param f64 f64) (result f64)))
(export "add" (func $add))
(export "subtract" (func $subtract))
(export "multiply" (func $multiply))
(export "divide" (func $divide))
(func $add (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local.set $2
(i32.add
(local.get $0)
(local.get $1)
)
)
(return
(local.get $2)
)
)
(func $subtract (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local.set $2
(i32.sub
(local.get $0)
(local.get $1)
)
)
(return
(local.get $2)
)
)
(func $multiply (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local.set $2
(i32.mul
(local.get $0)
(local.get $1)
)
)
(return
(local.get $2)
)
)
(func $divide (param $0 f64) (param $1 f64) (result f64)
(local $2 f64)
(local.set $2
(f64.div
(local.get $0)
(local.get $1)
)
)
(return
(local.get $2)
)
)
(func $deadcode (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local.set $2
(i32.div_u
(local.get $0)
(local.get $1)
)
)
(return
(local.get $2)
)
)
)
WebAssembly को ऑप्टिमाइज़ करना
Binaryen, Wasm कोड को ऑप्टिमाइज़ करने के दो तरीके उपलब्ध कराता है. एक Binaryen.js में और दूसरा कमांड लाइन के लिए. पहले विकल्प में, डिफ़ॉल्ट रूप से ऑप्टिमाइज़ेशन के नियमों का स्टैंडर्ड सेट लागू होता है. साथ ही, इसमें ऑप्टिमाइज़ और श्रिंक लेवल सेट करने की सुविधा मिलती है. वहीं, दूसरे विकल्प में डिफ़ॉल्ट रूप से कोई नियम लागू नहीं होता. हालांकि, इसमें पूरी तरह से पसंद के मुताबिक बनाने की सुविधा मिलती है. इसका मतलब है कि एक्सपेरिमेंट के बाद, अपने कोड के हिसाब से सबसे अच्छे नतीजे पाने के लिए, सेटिंग को अपनी ज़रूरत के मुताबिक बनाया जा सकता है.
Binaryen.js का इस्तेमाल करके ऑप्टिमाइज़ करना
Binaryen की मदद से किसी Wasm मॉड्यूल को ऑप्टिमाइज़ करने का सबसे आसान तरीका यह है कि Binaryen.js के Module#optimize()
तरीके को सीधे तौर पर कॉल किया जाए. इसके अलावा, ऑप्टिमाइज़ेशन और श्रिंक लेवल को सेट किया जा सकता है.
// Assume the `wast` variable contains a Wasm program.
const module = binaryen.parseText(wast);
binaryen.setOptimizeLevel(2);
binaryen.setShrinkLevel(1);
// This corresponds to the `-Os` setting.
module.optimize();
ऐसा करने से, पहले से मौजूद डेड कोड हट जाता है. इसलिए, ExampleScript के Wasm वर्शन के टेक्स्ट वाले वर्शन में अब यह कोड नहीं दिखता. यह भी ध्यान दें कि local.set/get
पेयर को ऑप्टिमाइज़ेशन के इन चरणों से कैसे हटाया जाता है: SimplifyLocals (स्थानीय सेटिंग से जुड़े अलग-अलग ऑप्टिमाइज़ेशन) और Vacuum (ज़रूरत न होने वाले कोड को हटाता है). साथ ही, return
को RemoveUnusedBrs (ज़रूरत न होने वाली जगहों से ब्रेक हटाता है) से कैसे हटाया जाता है.
(module
(type $0 (func (param i32 i32) (result i32)))
(type $1 (func (param f64 f64) (result f64)))
(export "add" (func $add))
(export "subtract" (func $subtract))
(export "multiply" (func $multiply))
(export "divide" (func $divide))
(func $add (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32)
(i32.add
(local.get $0)
(local.get $1)
)
)
(func $subtract (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32)
(i32.sub
(local.get $0)
(local.get $1)
)
)
(func $multiply (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32)
(i32.mul
(local.get $0)
(local.get $1)
)
)
(func $divide (; has Stack IR ;) (param $0 f64) (param $1 f64) (result f64)
(f64.div
(local.get $0)
(local.get $1)
)
)
)
कई ऑप्टिमाइज़ेशन पास होते हैं. साथ ही, Module#optimize()
ऑप्टिमाइज़ और श्रिंक लेवल के डिफ़ॉल्ट सेट का इस्तेमाल करता है. पूरी तरह से पसंद के मुताबिक बनाने के लिए, आपको कमांड लाइन टूल wasm-opt
का इस्तेमाल करना होगा.
wasm-opt कमांड लाइन टूल की मदद से ऑप्टिमाइज़ करना
इस्तेमाल किए जाने वाले पास को पूरी तरह से पसंद के मुताबिक बनाने के लिए, Binaryen में wasm-opt
कमांड लाइन टूल शामिल होता है. ऑप्टिमाइज़ेशन के सभी संभावित विकल्पों की पूरी सूची पाने के लिए, टूल का सहायता मैसेज देखें. wasm-opt
टूल, शायद सबसे ज़्यादा लोकप्रिय टूल है. इसका इस्तेमाल कई कंपाइलर टूलचेन, Wasm कोड को ऑप्टिमाइज़ करने के लिए करते हैं. इनमें Emscripten, J2CL, Kotlin/Wasm, dart2wasm, wasm-pack वगैरह शामिल हैं.
wasm-opt --help
पास के बारे में जानकारी देने के लिए, यहां कुछ पास के बारे में बताया गया है. इन्हें समझने के लिए, विशेषज्ञ होने की ज़रूरत नहीं है:
- CodeFolding: यह कोड को मर्ज करके डुप्लीकेट कोड से बचाता है. उदाहरण के लिए, अगर दो
if
आर्म के आखिर में कुछ निर्देश एक जैसे हैं. - DeadArgumentElimination: यह लिंक टाइम ऑप्टिमाइज़ेशन पास है. इसका इस्तेमाल, किसी फ़ंक्शन के ऐसे आर्ग्युमेंट को हटाने के लिए किया जाता है जिन्हें हमेशा एक ही कॉन्स्टेंट के साथ कॉल किया जाता है.
- MinifyImportsAndExports: यह विकल्प, इंपोर्ट और एक्सपोर्ट को
"a"
और"b"
में छोटा करता है. - DeadCodeElimination: डेड कोड हटाएं.
ऑप्टिमाइज़ेशन कुकबुक उपलब्ध है. इसमें कई तरह के फ़्लैग की पहचान करने के बारे में सुझाव दिए गए हैं. इससे यह पता चलता है कि कौनसे फ़्लैग ज़्यादा अहम हैं और उन्हें सबसे पहले आज़माना चाहिए. उदाहरण के लिए, कभी-कभी wasm-opt
को बार-बार चलाने से, इनपुट और छोटा हो जाता है. ऐसे मामलों में, --converge
फ़्लैग के साथ कैंपेन चलाने पर, ऑप्टिमाइज़ेशन तब तक होता रहता है, जब तक कि कोई और ऑप्टिमाइज़ेशन नहीं हो जाता और एक तय पॉइंट पर नहीं पहुंच जाता.
डेमो
इस पोस्ट में बताए गए कॉन्सेप्ट को काम करते हुए देखने के लिए, एम्बेड किए गए डेमो का इस्तेमाल करें. इसमें ExampleScript का कोई भी इनपुट दिया जा सकता है. यह भी पक्का करें कि आपने डेमो का सोर्स कोड देखा हो.
मीटिंग में सामने आए नतीजे
Binaryen, भाषाओं को WebAssembly में कंपाइल करने और उससे मिलने वाले कोड को ऑप्टिमाइज़ करने के लिए एक बेहतरीन टूलकिट उपलब्ध कराता है. इसकी JavaScript लाइब्रेरी और कमांड-लाइन टूल, इस्तेमाल करने में आसान होते हैं और इनमें कई तरह के विकल्प मिलते हैं. इस पोस्ट में, Wasm कंपाइलेशन के मुख्य सिद्धांतों के बारे में बताया गया है. साथ ही, Binaryen की असरदार क्षमता और ज़्यादा से ज़्यादा ऑप्टिमाइज़ेशन की संभावना के बारे में हाइलाइट किया गया है. Binaryen के ऑप्टिमाइज़ेशन को पसंद के मुताबिक बनाने के लिए, कई विकल्पों में Wasm के इंटरनल के बारे में ज़्यादा जानकारी की ज़रूरत होती है. हालांकि, आम तौर पर डिफ़ॉल्ट सेटिंग पहले से ही अच्छी तरह से काम करती हैं. इसके साथ ही, Binaryen का इस्तेमाल करके कंपाइल और ऑप्टिमाइज़ करने के लिए शुभकामनाएं!
Acknowledgements
इस पोस्ट की समीक्षा ऐलन ज़काई, थॉमस लाइवली, और राशेल ऐंड्रयू ने की है.