Чи інтерпретується JavaScript дизайном?


73

Мені з обережністю ставиться це запитання, оскільки воно може здатися надто прискіпливим. Щойно я відкрив JavaScript: Посібник, що визначається, і в ньому йдеться про першу сторінку глави 1

"JavaScript - це висока, динамічна, нетипізована інтерпретована мова програмування"

Тож я повинен вважати, що інтерпретована частина є вимогою в специфікації мови, чи вводити в оману твердження, що мова є інтерпретованою мовою програмування при повазі різниці між мовою та її багатьма реалізаціями?

Мабуть, немає статичних компіляторів для JavaScript - https://stackoverflow.com/questions/1118138/is-there-a-native-machine-code-compiler-for-javascript, тож, можливо, це просто відображення цього.


Деякий час jscript.net був схожий на AS3 / "загублений" ES4. Це був байт-код, зібраний у CIL.
Гей,

13
V8 прямо заявляє, що не є перекладачем, а компілятором.
pimvdb

@GGG JScript.Net все ще живий і ... хворий. Але все-таки живий. msdn.microsoft.com/en-us/library/72bd815a.aspx
Jetti

1
FWIW, "нетипізований" біт теж не є строго вірним
Роб Агар

Firefox тільки що випустив перший компілятор JIT на базі браузера, коли на це питання відповіли у FF 3.5, тому про нього, мабуть, мало відомо. Я вважаю, що сучасні JIT насправді дуже багато збирають (або принаймні готують до компіляції) під час першого проходження документа JS, щоб зробити такі речі, як методи ідентифікації та кешування, які відокремлені для заданої області.
Ерік Реппен

Відповіді:


50

Тож я повинен вважати, що інтерпретована частина є вимогою в специфікації мови, чи вводити в оману твердження, що мова є інтерпретованою мовою програмування при повазі різниці між мовою та її багатьма реалізаціями?

Ексмакрипські мові вуха часто використовують термін "інтерпретатор ES" для позначення реалізації EcmaScript, але специфікація не використовує цей термін. Зокрема, огляд мови описує мову в перекладно-агностичних термінах:

ECMAScript базується на об'єктах: основна мова та засоби хосту забезпечуються об'єктами, а програма ECMAScript - це кластер об'єктів, що спілкуються.

Таким чином, EcmaScript передбачає "середовище хоста", яке визначається як постачальник визначень об'єктів, включаючи всі ті, які дозволяють введення-виведення або будь-які інші посилання на зовнішній світ, але не вимагають перекладача.

Семантика висловлювань та виразів у мові визначається з точки зору специфікації завершення, яка тривіально реалізована в інтерпретаторі, але специфікація цього не вимагає.

8.9 Тип специфікації завершення

Тип Завершення використовується для пояснення поведінки операторів ( break, continue, returnі throw) , які виконують нелокальних передачу управління. Значення типу завершення - це потрійні форми ( тип , значення , ціль ), де тип є нормальним , перервати , продовжити , повернути або кинути , значення - це будь-яке значення мови ECMAScript або порожнє , а цільовим є будь-який ідентифікатор ECMAScript або порожній .

Термін "раптове завершення" позначає будь-яке завершення типу, відмінного від звичайного .

Нелокальні передачі управління можуть бути перетворені в масиви інструкцій зі стрибками, що дозволяють створити нативний або байт-код.

"EcmaScript Engine" може бути кращим способом висловити ту саму ідею.


Мабуть, немає статичних компіляторів для JavaScript

Це не правда. "Інтерпретатор" V8 компілюється всередині нативного коду, Rhino необов'язково компілюється в байт-код Java внутрішньо, а різні інтерпретатори Mozilla ({Trace, Spider, Jager} Monkey) використовують компілятор JIT.

V8 :

V8 підвищує продуктивність, компілюючи JavaScript до власного машинного коду перед його виконанням, порівняно з виконанням байт-коду або інтерпретацією.

Носоріг :

public final void setOptimizationLevel(int optimizationLevel)

Встановіть поточний рівень оптимізації. Очікується, що рівень оптимізації буде цілим числом від -1 до 9. Будь-які негативні значення будуть інтерпретовані як -1, а будь-які значення, що перевищують 9, будуть інтерпретовані як 9. Рівень оптимізації -1 означає, що режим інтерпретації завжди буде б / в. Рівні від 0 до 9 вказують на те, що файли класу можуть створюватися. Більш високі рівні оптимізації знижують час компіляції для виконання. Рівень оптимізатора не можна встановити більше -1, якщо пакет оптимізатора не існує під час виконання.

TraceMonkey :

TraceMonkey додає компіляцію нативного коду до двигуна JavaScript®® Mozilla (відомого як "SpiderMonkey"). Він заснований на методиці, розробленій в UC Irvine під назвою "сліди дерев", і базуючись на коді та ідеях, поділених проектом Tamarin Tracing. Результатом цього є значне збільшення швидкості як для хромування браузера, так і для вмісту веб-сторінок.


1
Дякую за цю відповідь, вона фактично відповідає на питання. Я припускаю, що остаточний коментар про відсутність статичної компіляції - це те, що спричинило невдачу щодо того, які реалізації насправді складають код, а які - ні. Мене зацікавило лише обгрунтованість твердження "JavaScript - інтерпретована мова", яке, враховуючи цитати реалізації та відсутність визначення специфікації, видається помилковим. Не підбадьорює другий абзац "Постійного посібника", але, мабуть, я його дотримуватимусь.
Метт Еш

@ me232, це твердження було правдивим до 2008 року. Rhino наперед датував це, але не був основним перекладачем, і так мало хто з них винив би "Визначальний посібник" в той час, коли його ігнорував. Я не читав книгу, тому не можу коментувати, наскільки репрезентативним є таке речення в цілому.
Майк Самуель

Що таке визначення "статичний компілятор". Я подумав, що визначення означає, що компіляція відбувається лише один раз, і ви отримуєте статичне (тобто незмінне) відро бітів, яке потім виконуєте. AFAIK це не так, як працює будь-який двигун JavaScript. Тому вони мають de-optimizationкроки. Іншими словами, JavaScript компілюється цими двигунами, але він статично не компілюється.
gman

@gman, таким чином працює генератор байтових кодів Rhino.
Майк Самуель

AFAIK це не так. Rhino може включати інші файли JavaScript, які потрібно скомпілювати під час виконання. Це не статичне ускладнення.
gman

20

VM JavaScript V8, який використовується в Chrome, не включає перекладача. Натомість він складається з двох компіляторів і збирає код на льоту. Один з компіляторів працює швидко, але генерує неефективний код, інший - оптимізуючий компілятор.

Я можу зрозуміти, чому деякі люди вважають це "обманом", оскільки V8 приймає вихідний код як вхідний при кожному запуску коду і користувачеві потрібно встановити V8. Але розглянемо компілятор, який видає виконуваний файл, який включає повний інтерпретатор і байт-код. Тоді ви мали б автономну програму. Це було б не дуже ефективно.


19

Поява компіляторів JIT для мов скриптів розмила межу між компіляцією та інтерпретацією до тієї точки, коли питання не означає все так сильно. Це лише інтерпретація, коли двигун зчитує рядок коду і негайно виконує його? (Сценарії оболонки все ще зазвичай реалізовані таким чином.) Чи є інтерпретація, коли двигун бере весь файл, негайно компілює його в якийсь байт-код, а потім інтерпретує байт-код? (Двигун Mozilla на першому етапі працює таким чином, як і CPython.) Чи є інтерпретація, коли двигун одночасно аналізує функцію і JIT-компілює її у нативний код? А як щодо тих двигунів, які складають весь файл у байт-код, а потім JIT по одній функції за потребою? (Більшість двигунів сценаріїв сьогодні працюють таким чином,

Між складанням та інтерпретацією існує багато відтінків.

Я думаю, що найбільш корисне визначення для інтерпретації - "подається вихідний код програми під час виконання, без окремого попереднього кроку". За цим визначенням усі двигуни JavaScript є перекладачами. Але це, звичайно, не єдине можливе визначення тлумачення.

Але чи розроблений JavaScript для інтерпретації? Зрештою, так: він має evalфункцію, а також Functionконструктор, який ви можете надати програмний код у вигляді рядка, який буде виконуватися. Уміння динамічно конструювати програмний код під час виконання вимагає, щоб двигун міг інтерпретувати вихідний код. Але це не означає, що ви не можете зробити все інше заздалегідь. Навіть у мові, складеній на зразок C ++ та C #, ви можете взяти вихідний код, скласти його в пам'яті до нового машинного коду та виконати це. Для цього є навіть бібліотеки: LLVM + Clang в C ++ і проект Roslyn в C #.

Також механізм доставки JavaScript є вихідним кодом; не існує розпізнаної форми байтового коду. C # і Java мають свій офіційний байт-код, і всі очікують, що C ++ буде доставлений як машинний код. Але це все ще не властивий аспект, якщо мова, просто домінуючий сценарій використання. Насправді, близький родич JavaScript JavaScript ActionScript у Flash насправді доставляється у вигляді байтового коду (компілятор Flash попередньо компілює всі сценарії).


4

Не існує повністю узгодженого визначення поняття "інтерпретоване" проти "складеного". У класичному розрізненні компільовані мови створюють автономний бінарний виконуваний файл, тоді як інтерпретовані мови вимагають розгорнутого режиму виконання для виконання коду. Віртуальні машини, байт-код тощо - розмиває відмінність.

Але ось можливо корисне визначення: інтерпретована мова - це мова, де стандартна мова виконання може приймати текст вихідного коду як вхідний і виконувати його. За цим визначенням інтерпретуються сценарії Perl, Python, Ruby, JavaScript та оболонки тощо (навіть якщо вони використовують проміжні кроки, такі як байт-код або навіть власний код). Java, C #, C тощо не є. І JavaScript за визначенням тлумачиться, навіть якщо специфікація не використовує точне слово.


Хм, мені не подобається ставити Java та C в одну категорію. Можливо, краще розрізняти мови, які найчастіше розповсюджуються як (A) вихідний код, (B) проміжний код або (C) машинний код. Наприклад A = javascript, B = Java, C = C.
Джон Генкель

Викликати мову, інтерпретовану чи складену, невірно. Наприклад, згідно з цим правилом ви погоджуєтесь, що C ++ є компільованою мовою правильно? Тоді, що з Cling, який виконує код c ++, не компілюючи його. "тощо" інтерпретується (навіть якщо вони використовують проміжні кроки, такі як байт-код або навіть власний код) "Відповідно до цього, java також інтерпретується, інтерпретується його VM.
Абхінав Гауніял
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.