<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JL&#039;s blog &#187; O&#8217;Browser</title>
	<atom:link href="http://john.5070.info/tag/obrowser/feed/" rel="self" type="application/rss+xml" />
	<link>http://john.5070.info</link>
	<description>:-)</description>
	<lastBuildDate>Sun, 06 Dec 2009 17:11:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JavaScript: безопасный код</title>
		<link>http://john.5070.info/2009/10/javascript-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4/</link>
		<comments>http://john.5070.info/2009/10/javascript-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 03:00:56 +0000</pubDate>
		<dc:creator>John Lepikhin</dc:creator>
				<category><![CDATA[Ocaml]]></category>
		<category><![CDATA[программирование]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[O'Browser]]></category>
		<category><![CDATA[ocamljs]]></category>

		<guid isPermaLink="false">http://john.5070.info/?p=193</guid>
		<description><![CDATA[Давно собирался написать нечто подобное, да всё руки не доходили. Толчком послужил краткий пост на аналогичную тему у моего знакомого.
Как известно, JavaScript — язык c динамической (для классов с утиной) типизацией, с очень плохо развитой системой типов. Стандартный интерпретатор даже в браузерах Mozilla с расширениями разработчика отлавливает минимум ошибок. Практически все эти ошибки — синтаксические. [...]]]></description>
			<content:encoded><![CDATA[<p>Давно собирался написать нечто подобное, да всё руки не доходили. Толчком послужил краткий пост на аналогичную тему у моего знакомого.</p>
<p>Как известно, JavaScript — язык c динамической (для классов с утиной) типизацией, с очень плохо развитой системой типов. Стандартный интерпретатор даже в браузерах Mozilla с расширениями разработчика отлавливает минимум ошибок. Практически все эти ошибки — синтаксические. В результате, писать надёжный код на JavaScript предельно сложно. Положение усугубляет фактическая невозможность запуска программы без использования браузера, т.е. нет никакой песочницы для тестов.</p>
<p>В этой статье я попытаюсь описать некоторые технологии, которые помогут знакомому с Ocaml человеку существенно сократить время написания безопасного, стабильного и более-менее компактного JS-кода. Впрочем, описываемые техники есть и для некоторых других языков с развитой системой типов (например, Haskell).</p>
<p><span id="more-193"></span></p>
<h1>Ocamljs: компилятор Ocaml ⇒ JavaScript</h1>
<p>Скачать: <a href="http://code.google.com/p/ocamljs/">http://code.google.com/p/ocamljs/</a></p>
<p>Всё просто: вы пишете client-side код вашего сайта на Ocaml, а с помощью этого компилятора получаете готовый для использования в браузере JavaScript. Для обеспечения работы, непосредственно к вашему скрипту дописывается около 40KB дополнительного кода. Например. Ни к чему не обязывающий код:</p>

<div class="wp_syntax"><div class="code"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> tree <span style="color: #a52a2a;">=</span>
	<span style="color: #a52a2a;">|</span> Leaf <span style="color: #06c; font-weight: bold;">of</span> int
	<span style="color: #a52a2a;">|</span> Node <span style="color: #06c; font-weight: bold;">of</span> tree list
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> l <span style="color: #a52a2a;">:</span> tree list <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> _ <span style="color: #a52a2a;">=</span>
	<span style="color: #06c; font-weight: bold;">match</span> l <span style="color: #06c; font-weight: bold;">with</span>
	<span style="color: #a52a2a;">|</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> <span style="color: #a52a2a;">-&gt;</span> Dom<span style="color: #a52a2a;">.</span><span style="color: #060;">window</span><span style="color: #a52a2a;">#</span>alert <span style="color: #3cb371;">&quot;empty list&quot;</span>
	<span style="color: #a52a2a;">|</span> a <span style="color: #a52a2a;">::</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span>
	<span style="color: #a52a2a;">|</span> a <span style="color: #a52a2a;">::</span> b <span style="color: #a52a2a;">::</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span>
	<span style="color: #a52a2a;">|</span> _ <span style="color: #a52a2a;">-&gt;</span> Dom<span style="color: #a52a2a;">.</span><span style="color: #060;">window</span><span style="color: #a52a2a;">#</span>alert <span style="color: #3cb371;">&quot;unexpected list&quot;</span></pre></div></div>

<p>Компилируем:</p>
<pre>ocamljs -o test.js -I /usr/local/lib/ocaml/3.10.2/dom/ dom.cmjsa test.ml</pre>
<p>Получаем вот такой код:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// .....</span>
<span style="color: #003366; font-weight: bold;">var</span> oc$Dom$ <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">var</span> window$<span style="color: #CC0000;">717</span> <span style="color: #339933;">=</span> window<span style="color: #339933;">;</span>
                            <span style="color: #003366; font-weight: bold;">var</span> document$<span style="color: #CC0000;">718</span> <span style="color: #339933;">=</span> document<span style="color: #339933;">;</span>
                            <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span>window$<span style="color: #CC0000;">717</span><span style="color: #339933;">,</span> document$<span style="color: #CC0000;">718</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oc$<span style="color: #CC0000;">1</span>$ <span style="color: #339933;">=</span>
  <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> l$<span style="color: #CC0000;">63</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> match$<span style="color: #CC0000;">71</span> <span style="color: #339933;">=</span> l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>match$<span style="color: #CC0000;">71</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>match$<span style="color: #CC0000;">71</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">var</span> v$<span style="color: #CC0000;">74</span> <span style="color: #339933;">=</span> oc$Dom$<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                                      <span style="color: #000066; font-weight: bold;">return</span> _m<span style="color: #009900;">&#40;</span>v$74.<span style="color: #000066;">alert</span><span style="color: #339933;">,</span> v$<span style="color: #CC0000;">74</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;unexpected list&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #003366; font-weight: bold;">var</span> v$<span style="color: #CC0000;">73</span> <span style="color: #339933;">=</span> oc$Dom$<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">return</span> _m<span style="color: #009900;">&#40;</span>v$73.<span style="color: #000066;">alert</span><span style="color: #339933;">,</span> v$<span style="color: #CC0000;">73</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;empty list&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span>l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oc$Std_exit$ <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>_<span style="color: #009900;">&#40;</span>oc$Pervasives$<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">80</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> $<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> caml_named_value<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>JavaScript compressor</h2>
<p>Как я уже сказал, код получается достаточно объёмным. Частично эту проблему решает gzip (при условии, что и сервер, и браузер имеют его поддержку). Однако, код можно существенно сократить за счёт оптимизации по размеру. Для этого есть ряд готовых online-утилит. Используемые техники:</p>
<ul>
<li>Удаление комментариев</li>
<li>Удаление не несущих синтаксической нагрузки пробелов и переносов строк</li>
<li>Назначение локальным переменным функций более коротких имён</li>
<li>Вынесение длинных повторяющихся констант в переменную с коротким именем</li>
</ul>
<p>Наилучшие результаты показывает Packer (<a href="http://dean.edwards.name/packer/">http://dean.edwards.name/packer/</a>), однако ocamljs компилирует не полностью корректный код — иногда забывает точки с запятой — поэтому Packer генерирует не работающий код. С учётом некорректности оригинального кода, наилучший результат показал Dojo ShrinkSafe (<a href="http://www.dojotoolkit.org/docs/shrinksafe">http://www.dojotoolkit.org/docs/shrinksafe</a>). Рекомендую прогнать код через валидатор (<a href="http://jslint.com/">http://jslint.com/</a>), это в любом случае неплохая идея. Пример кода, получающегося с помощью Dojo ShrinkSafe:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// .....</span>
<span style="color: #003366; font-weight: bold;">var</span> _213<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> l$<span style="color: #CC0000;">63</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> _215<span style="color: #339933;">=</span>l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>_215<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>_215<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> v$<span style="color: #CC0000;">74</span><span style="color: #339933;">=</span>_210<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> _m<span style="color: #009900;">&#40;</span>v$74.<span style="color: #000066;">alert</span><span style="color: #339933;">,</span>v$<span style="color: #CC0000;">74</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;unexpected list&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> v$<span style="color: #CC0000;">73</span><span style="color: #339933;">=</span>_210<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> _m<span style="color: #009900;">&#40;</span>v$73.<span style="color: #000066;">alert</span><span style="color: #339933;">,</span>v$<span style="color: #CC0000;">73</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;empty list&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span>l$<span style="color: #CC0000;">63</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> _218<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>_<span style="color: #009900;">&#40;</span>_106<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">80</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>$<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> _9d<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Код получается практически не читаемым, зато размер сокращается в 2-4 раза.</p>
<p>Быстро сравнить различные компрессоры можно на сайте: <a href="http://compressorrater.thruhere.net/">http://compressorrater.thruhere.net/</a></p>
<h1>O&#8217;Browser: виртуальная машина на JavaScript</h1>
<p>Скачать: <a href="http://ocsigen.org/obrowser/">http://ocsigen.org/obrowser/</a></p>
<p>Ваш код будет скомпилирован в байт-код, закодированный в UUE. Для вызова кода, достаточно вызвать его в виртуальной машине:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">&lt;script src=&quot;vm.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #009966; font-style: italic;">/* &lt;![CDATA[ */</span>
    window.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      exec_caml <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;tutorial.exe.uue&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009966; font-style: italic;">/* ]]&gt; */</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Байт-код получается достаточно объёмным, да и сжатию поддаётся только за счёт слоя gzip. Впрочем, код самой виртуальной машины вполне поддаётся обработке JavaScript компрессоров. Валидность кода получается даже выше, чем у ocamljs. Декомпиляция байт-кода в нормальный JavaScript становится нерешаемой проблемой :)</p>
]]></content:encoded>
			<wfw:commentRss>http://john.5070.info/2009/10/javascript-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
