Προγραμματισμός

Εκκινητής WebAssembly: Ξεκινήστε με το WebAssembly

Το WebAss Assembly υπόσχεται ένα ολοκαίνουργιο είδος ιστού — πιο γρήγορη απόδοση για τους χρήστες και μεγαλύτερη ευελιξία για τους προγραμματιστές. Αντί να κλειδωθεί στη χρήση JavaScript ως η μόνη γλώσσα για αλληλεπίδραση ιστού από τον πελάτη, ένας προγραμματιστής μπορεί να επιλέξει από ένα ευρύ φάσμα άλλων γλωσσών - C, TypeScript, Rust, Ruby, Python - και να εργαστεί σε αυτήν που είναι πιο άνετη με.

Αρχικά, ο μόνος τρόπος για να δημιουργήσετε WebAssembly (ή WASM για συντομία) ήταν να μεταγλωττίσετε κώδικα C / C ++ στο WebAssembly χρησιμοποιώντας την εργαλειοθήκη Emscripten. Σήμερα, όχι μόνο οι προγραμματιστές έχουν περισσότερες επιλογές γλώσσας, αλλά έχει γίνει ευκολότερο να μεταγλωττιστούν αυτές οι άλλες γλώσσες απευθείας στο WebAssembly, με λιγότερα παρεμβαλλόμενα βήματα.

Σε αυτό το κομμάτι, θα εξετάσουμε τα βήματα που απαιτούνται για την εφαρμογή στοιχείων WebAss Assembly σε μια εφαρμογή ιστού. Επειδή το WebAssembly είναι μια διαδικασία σε εξέλιξη, τα βήματα εξαρτώνται σε μεγάλο βαθμό από τη γλώσσα που χρησιμοποιείτε και η αλυσίδα εργαλείων είναι πιθανό να συνεχίσει να αλλάζει για κάποιο χρονικό διάστημα. Αλλά αυτήν τη στιγμή, είναι δυνατό να γράψετε και να αναπτύξετε χρήσιμες, αν είναι ελάχιστες, εφαρμογές WebAss Assembly σε διάφορες γλώσσες.

Επιλέξτε μια γλώσσα που υποστηρίζεται από το WebAss Assembly

Το πρώτο βήμα προς την ανάπτυξη μιας εφαρμογής WebAssembly είναι να επιλέξετε μια γλώσσα που μπορεί να μεταγλωττιστεί στο WebAssembly ως στόχο. Υπάρχει μια καλή πιθανότητα τουλάχιστον μία από τις κύριες γλώσσες που χρησιμοποιείτε στην παραγωγή να μπορεί να μετατραπεί σε WebAssembly ή να διαθέτει μεταγλωττιστή που μπορεί να εκπέμπει WebAssembly.

Εδώ είναι οι πρώτοι δρομείς:

  • ΝΤΟ. Προφανώς. Ο τυπικός τρόπος για να μετατρέψετε τον κώδικα C σε WebAssembly είναι μέσω του Emscripten, καθώς το C-to-Emscripten-to-WebAssembly ήταν η πρώτη αλυσίδα εργαλείων WebAssembly που εμφανίστηκε. Αλλά εμφανίζονται και άλλα εργαλεία. Ένας ολόκληρος μεταγλωττιστής, το Cheerp, έχει σχεδιαστεί ειδικά για τη δημιουργία εφαρμογών WebAss Assembly από τον κώδικα C / C ++. Το Cheerp μπορεί επίσης να στοχεύσει JavaScript, asm.js ή οποιονδήποτε συνδυασμό των παραπάνω. Είναι επίσης δυνατό να χρησιμοποιήσετε την αλυσίδα εργαλείων Clang για να δημιουργήσετε ωφέλιμα φορτία WebAss Assembly, αν και η διαδικασία απαιτεί ακόμα πολλή χειροκίνητη ανύψωση. (Εδώ είναι ένα παράδειγμα.)
  • Σκουριά. Η γλώσσα προγραμματισμού συστημάτων του Mozilla, σχεδιασμένη να είναι ασφαλής και γρήγορη, είναι ένας από τους σημαντικότερους υποψηφίους ντόπιος Υποστήριξη WebAss Assembly. Οι επεκτάσεις στην αλυσίδα εργαλείων Rust σάς επιτρέπουν να μεταγλωττίζετε απευθείας από τον κώδικα Rust στο WebAssembly Πρέπει να χρησιμοποιήσετε το Rust's κάθε βράδυ αλυσίδα εργαλείων για την εκτέλεση συλλογής WebAss Assembly, επομένως αυτή η λειτουργία πρέπει να θεωρηθεί πειραματική προς το παρόν.
  • Τύπος γραφής. Από προεπιλογή, το TypeScript μεταγλωττίζεται σε JavaScript, που σημαίνει ότι θα μπορούσε με τη σειρά του να μεταγλωττιστεί στο WebAssembly. Το έργο AssemblyScript μειώνει τον αριθμό των σχετικών βημάτων, επιτρέποντας τη σύνταξη αυστηρά δακτυλογραφημένου TypeScript στο WebAssembly.

Πολλές άλλες γλώσσες αρχίζουν να στοχεύουν στο WebAss Assembly, αλλά βρίσκονται σε πολύ πρώιμο στάδιο. Οι ακόλουθες γλώσσες μπορούν να χρησιμοποιηθούν για τη δημιουργία στοιχείων WebAss Assembly, αλλά μόνο με πιο περιορισμένους τρόπους από τους C, Rust και TypeScript:

  • ρε. Η γλώσσα D πρόσθεσε πρόσφατα υποστήριξη για τη μεταγλώττιση και τη σύνδεση απευθείας στο WebAssembly.
  • Ιάβα. Το Java bytecode μπορεί να μεταγλωττιστεί εκ των προτέρων στο WebAss Assembly μέσω του έργου TeaVM. Αυτό σημαίνει όποιος Η γλώσσα που εκπέμπει Java bytecode μπορεί να μεταγλωττιστεί στο WebAssembly - για παράδειγμα, Kotlin, Scala ή Clojure. Ωστόσο, πολλά από τα Java API που δεν μπορούν να εφαρμοστούν αποτελεσματικά στο WebAssembly είναι περιορισμένα, όπως το API προβληματισμού και πόρων, έτσι το TeaVM - και επομένως το WebAssembly - χρησιμοποιείται μόνο για ένα υποσύνολο εφαρμογών που βασίζονται σε JVM.
  • Λούα. Η γλώσσα δέσμης ενεργειών Lua έχει μακρά ιστορία χρήσης ως ενσωματωμένη γλώσσα, όπως και η JavaScript. Ωστόσο, τα μόνα έργα για τη μετατροπή του Lua σε WebAssembly περιλαμβάνουν τη χρήση μιας μηχανής εκτέλεσης στο πρόγραμμα περιήγησης: το wasm_lua ενσωματώνει έναν χρόνο εκτέλεσης Lua στο πρόγραμμα περιήγησης, ενώ το Luwa JIT μεταγλωττίζει το Lua στο WebAssembly
  • Κότλιν / Εγγενής. Οι οπαδοί της γλώσσας Kotlin, ένα spin-off της Java, περιμένουν με ανυπομονησία την πλήρη κυκλοφορία του Kotlin / Native, ενός LLVM back end για τον μεταγλωττιστή Kotlin που μπορεί να παράγει αυτόνομα δυαδικά αρχεία. Το Kotlin / Native 0.4 εισήγαγε την υποστήριξη για το WebAss Assembly ως στόχο συλλογής, αλλά μόνο ως απόδειξη της ιδέας.
  • .Καθαρά. Οι γλώσσες .Net δεν διαθέτουν πλήρη υποστήριξη WebAss Assembly, αλλά έχουν ξεκινήσει ορισμένα πειράματα. Δείτε το Blazor, το οποίο μπορεί να χρησιμοποιηθεί για τη δημιουργία εφαρμογών ιστού μίας σελίδας στο .Net μέσω C # και της σύνταξης «Razor» της Microsoft.
  • Νιμ. Αυτή η ανερχόμενη γλώσσα μεταγλωττίζεται στο C, οπότε θεωρητικά θα μπορούσε να μεταγλωττιστεί το προκύπτον C στο WebAss Assembly. Ωστόσο, ένα πειραματικό back end για τον Nim που ονομάζεται nwasm βρίσκεται υπό ανάπτυξη.
  • Άλλες γλώσσες που υποστηρίζονται από LLVM. Θεωρητικά, οποιαδήποτε γλώσσα που αξιοποιεί το πλαίσιο μεταγλωττιστή LLVM μπορεί να μεταγλωττιστεί στο WebAssembly, καθώς το LLVM υποστηρίζει το WebAssembly ως έναν από τους πολλούς στόχους. Ωστόσο, αυτό δεν σημαίνει απαραίτητα ότι οποιαδήποτε γλώσσα που έχει μεταγλωττιστεί LLVM θα εκτελείται όπως είναι στο WebAssembly. Αυτό σημαίνει απλώς ότι το LLVM διευκολύνει τη στόχευση WebAss Assembly.

Όλα τα παραπάνω έργα μετατρέπουν το αρχικό πρόγραμμα ή δημιουργήθηκε bytecode σε WebAssembly. Αλλά για ερμηνευμένες γλώσσες όπως το Ruby ή το Python, υπάρχει μια άλλη προσέγγιση: Αντί να μετατρέπονται οι ίδιες οι εφαρμογές, κάποιος μετατρέπει τη γλώσσα χρόνος εκτέλεσης στο WebAss Assembly. Στη συνέχεια, τα προγράμματα εκτελούνται ως έχει στον μετατρεπόμενο χρόνο εκτέλεσης. Δεδομένου ότι πολλοί χρόνοι εκτέλεσης γλώσσας (συμπεριλαμβανομένων των Ruby και Python) είναι γραμμένοι σε C / C ++, η διαδικασία μετατροπής είναι ουσιαστικά η ίδια με οποιαδήποτε άλλη εφαρμογή C / C ++.

Φυσικά αυτό σημαίνει ότι ο χρόνος εκτέλεσης που έχει μετατραπεί πρέπει να μεταφορτωθεί στο πρόγραμμα περιήγησης προτού εκτελεστούν οι εφαρμογές, επιβραδύνοντας τους χρόνους φόρτωσης και ανάλυσης. Μια «καθαρή» έκδοση WebAss Assembly μιας εφαρμογής είναι πιο ελαφριά. Έτσι, η μετατροπή χρόνου εκτέλεσης είναι στην καλύτερη περίπτωση ένα μέτρο διακοπής έως ότου περισσότερες γλώσσες υποστηρίζουν το WebAss Assembly ως στόχο εξαγωγής ή μεταγλώττισης.

Ενσωματώστε το WebAss Assembly με JavaScript

Το επόμενο βήμα είναι να γράψετε κώδικα στη γλώσσα που έχετε επιλέξει, με κάποια προσοχή στο πώς αυτός ο κώδικας θα αλληλεπιδρά με το περιβάλλον WebAssembly, στη συνέχεια να τον μεταγλωττίσετε σε μια λειτουργική μονάδα WebAssembly (ένα δυαδικό WASM) και τελικά να ενσωματώσετε αυτήν τη λειτουργική μονάδα με μια υπάρχουσα Εφαρμογή JavaScript.

Τα ακριβή βήματα για τον τρόπο εξαγωγής του κώδικα στο WebAss Assembly θα ποικίλλουν σε μεγάλο βαθμό ανάλογα με την εργαλειοθήκη. Θα παρεκκλίνουν επίσης κάπως από τον τρόπο που δημιουργούνται τα κανονικά εγγενή δυαδικά αρχεία για αυτήν τη γλώσσα. Για παράδειγμα, στο Rust, θα πρέπει να ακολουθήσετε διάφορα βήματα:

  1. Ρυθμίστε το κάθε βράδυ χτίστε για Rust, με το wasm32-άγνωστο-άγνωστο αλυσίδα εργαλείων.
  2. Γράψτε τον κωδικό Rust με εξωτερικές λειτουργίες που δηλώνονται ως # [όχι-μπερδεμένο].
  3. Δημιουργήστε τον κώδικα χρησιμοποιώντας την παραπάνω αλυσίδα εργαλείων.

(Για μια αναλυτική περιγραφή των παραπάνω βημάτων, ανατρέξτε στο Βιβλίο The Rust and WebAss Assembly στο GitHub.)

Αξίζει να σημειωθεί ότι ανεξάρτητα από τη γλώσσα που χρησιμοποιείτε, θα πρέπει να έχετε τουλάχιστον ένα ελάχιστο επίπεδο επάρκειας στη JavaScript για να ενσωματώσετε τον κώδικα σε μια διεπαφή HTML. Εάν τα αποσπάσματα JavaScript στη σελίδα σε αυτό το παράδειγμα από το βιβλίο Rust και WebAssembly φαίνεται ελληνικά για εσάς, αφιερώστε λίγο χρόνο για να μάθετε τουλάχιστον αρκετή JavaScript για να καταλάβετε τι συμβαίνει εκεί.

Η ενσωμάτωση του WebAssembly και JavaScript γίνεται χρησιμοποιώντας το WebAss Assembly αντικείμενο σε JavaScript για να δημιουργήσετε μια γέφυρα στον κώδικα WebAss Assembly σας. Η Mozilla έχει τεκμηρίωση για το πώς να το κάνει αυτό. Εδώ είναι ένα ξεχωριστό παράδειγμα WebAssembly για το Rust, και εδώ είναι ένα παράδειγμα WebAss Assembly για το Node.js.

Αυτήν τη στιγμή, η ενσωμάτωση μεταξύ του παρασκηνίου WebAss Assembly και της διεπαφής JavaScript / HTML εξακολουθεί να είναι το πιο δυσκίνητο και χειροκίνητο μέρος ολόκληρης της διαδικασίας. Για παράδειγμα, με το Rust, οι γέφυρες στο JavaScript πρέπει να δημιουργηθούν χειροκίνητα, μέσω ακατέργαστων δεικτών δεδομένων.

Ωστόσο, περισσότερα κομμάτια της αλυσίδας εργαλείων αρχίζουν να αντιμετωπίζουν αυτό το ζήτημα. Το πλαίσιο Cheerp επιτρέπει στους προγραμματιστές C ++ να μιλούν στα API του προγράμματος περιήγησης μέσω ενός ειδικού χώρου ονομάτων. Και η Rust προσφέρει wasm-bindgen, το οποίο χρησιμεύει ως αμφίδρομη γέφυρα μεταξύ JavaScript και Rust, και μεταξύ JavaScript και WebAssembly.

Επιπλέον, εξετάζεται μια πρόταση υψηλού επιπέδου για τον τρόπο χειρισμού των συνδέσμων στον κεντρικό υπολογιστή. Μόλις οριστικοποιηθεί, θα παρέχει έναν τυπικό τρόπο για τις γλώσσες που μεταγλωττίζονται στο WebAss assemb να αλληλεπιδρούν με κεντρικούς υπολογιστές. Η μακροπρόθεσμη στρατηγική με αυτήν την πρόταση περιλαμβάνει επίσης συνδέσεις σε κεντρικούς υπολογιστές που δεν είναι προγράμματα περιήγησης, αλλά οι δεσμεύσεις προγράμματος περιήγησης είναι η βραχυπρόθεσμη, άμεση χρήση.

Εντοπισμός σφαλμάτων και δημιουργία προφίλ για εφαρμογές WebAss Assembly

Ένας τομέας όπου το εργαλείο WebAss Assembly βρίσκεται ακόμη στα πρώτα στάδια είναι η υποστήριξη για εντοπισμό σφαλμάτων και δημιουργία προφίλ.

Μέχρι να εμφανιστούν οι χάρτες προέλευσης JavaScript, οι γλώσσες που μεταγλώττιζαν τη JavaScript ήταν συχνά δύσκολο να εντοπιστούν, επειδή ο αρχικός και ο μεταγλωττισμένος κώδικας δεν μπορούσαν να συσχετιστούν εύκολα. Το WebAssembly έχει μερικά από τα ίδια προβλήματα: Εάν γράφετε κώδικα σε C και τον μεταγλωττίσετε στο WASM, είναι δύσκολο να σχεδιάσετε συσχετισμούς μεταξύ της πηγής και του μεταγλωττισμένου κώδικα.

Οι χάρτες πηγής JavaScript δείχνουν ποιες γραμμές στον πηγαίο κώδικα αντιστοιχούν σε ποιες περιοχές του μεταγλωττισμένου κώδικα. Ορισμένα εργαλεία WebAss Assembly, όπως το Emscripten, μπορούν επίσης να εκπέμπουν χάρτες πηγής JavaScript για μεταγλωττισμένο κώδικα. Ένα από τα μακροπρόθεσμα σχέδια για το WebAssembly είναι ένα σύστημα χαρτών πηγών που υπερβαίνει ό, τι είναι διαθέσιμο σε JavaScript, αλλά εξακολουθεί να είναι μόνο στο στάδιο της πρότασης.

Αυτήν τη στιγμή, ο πιο άμεσος τρόπος για τον εντοπισμό σφαλμάτων κώδικα WASM είναι η χρήση της κονσόλας εντοπισμού σφαλμάτων του προγράμματος περιήγησης ιστού. Αυτό το άρθρο στο WebAssemblyCode δείχνει πώς μπορείτε να δημιουργήσετε κώδικα WASM με έναν πηγαίο χάρτη, να τον διαθέσετε στα εργαλεία εντοπισμού σφαλμάτων του προγράμματος περιήγησης και να προχωρήσετε στον κώδικα. Σημειώστε ότι τα βήματα που περιγράφονται εξαρτώνται από τη χρήση του emcc εργαλείο για να εκπέμψει το WASM. Ίσως χρειαστεί να τροποποιήσετε τα βήματα ανάλογα με τη συγκεκριμένη εργαλειοθήκη σας.