DELAEMON BLOG

Live as if you were to die tomorrow. Learn as if you were to live forever.

LLVM build on Fedora23(VirtualBox)

VirtualBox上のFedora23でLLVMをビルドした。

インストール手順

1. 必要パッケージをインストール

$ sudo dnf install make gcc-c++ texinfo m4 autoconf automake libtool graphviz python-xdot

2. ソースコードをダウンロード・解凍・配置

$ mkdir llvm
$ cd llvm/
$ wget http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz
$ wget http://llvm.org/releases/3.8.0/cfe-3.8.0.src.tar.xz
$ wget http://llvm.org/releases/3.8.0/compiler-rt-3.8.0.src.tar.xz

xz -dv llvm-3.8.0.src.tar.xz
tar -xvf llvm-3.8.0.src.tar
xz -dv cfe-3.8.0.src.tar.xz
tar xvf cfe-3.8.0.src.tar
mv cfe-3.8.0.src llvm-3.8.0.src/tools/clang
xz -dv compiler-rt-3.8.0.src.tar.xz
tar xvf compiler-rt-3.8.0.src.tar
mv compiler-rt-3.8.0.src llvm-3.8.0.src/projects/compiler-rt

3. ディレクトリを作成して、ビルド

$ mkdir llvm-build
$ cd llvm-build/
$ source ~/.bashrc
../llvm-3.8.0.src/configure --prefix=/usr/local/llvm --enable-optimized
$ make -j2
$ make check
$ sudo make install

かなり時間かかった。度々落ちるけど、メモリ不足だったので、make を繰り返せば終わる

基本操作
$ llvm
ll                llvm-as           llvm-diff         llvm-extract      llvm-nm           llvm-readobj      llvm-symbolizer
llc               llvm-bcanalyzer   llvm-dis          llvm-link         llvm-objdump      llvm-rtdyld       llvm-tblgen
lli               llvm-config       llvm-dsymutil     llvm-lto          llvm-pdbdump      llvm-size
lli-child-target  llvm-cov          llvm-dwarfdump    llvm-mc           llvm-profdata     llvm-split
llvm-ar           llvm-cxxdump      llvm-dwp          llvm-mcmarkup     llvm-ranlib       llvm-stress
$ clang -o hoge.o hoge.c
$ ./hoge.o
hoge
$ clang -emit-llvm -c -o hoge.bc hoge.c #LLVM ビットコードを出力
$ lli -force-interpreter hoge.bc #インタプリタで実行する
$ clang -emit-llvm -S -o hoge.ll hoge.c #LLVM アセンブリを出力
$ llvm-as -o hoge.bc hoge.ll #LLVM アセンブリをLLVM ビットコードへ変換
$ lli hoge.bc #実行
$ llc -o hoge.s hoge.bc #LLVM アセンブリを経由してアセンブリ出力
$ llc -filetype=obj -o hoge.o hoge.ll #オブジェクト出力
$ opt -O3 -o hoge.bc hoge.ll #最適化
$ lli hoge.bc #実行
$ llvm-objdump -d hoge.o #ディスアセンブル

hoge.o:	file format ELF64-x86-64

Disassembly of section .text:
main:
       0:	55 	pushq	%rbp
       1:	48 89 e5 	movq	%rsp, %rbp
       4:	bf 00 00 00 00 	movl	$0, %edi
       9:	31 c0 	xorl	%eax, %eax
       b:	e8 00 00 00 00 	callq	0 <main+10>
      10:	31 c0 	xorl	%eax, %eax
      12:	5d 	popq	%rbp

Clojure Leiningen

Clojureことはじめ

"Leiningen is the easiest way to use Clojure. With a focus on project automation and declarative configuration, it gets out of your way and lets you focus on your code."
Leiningen

leiningen をインストール

$ brew install leiningen

プロジェクトを作成

$ lein new hello

ディレクトリ構成は以下

$ tree
.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── dev-resources
├── doc
│   └── intro.md
├── project.clj
├── resources
├── src
│   └── hello
│       └── core.clj
├── target
│   ├── classes
│   │   └── META-INF
│   │       └── maven
│   │           └── hello
│   │               └── hello
│   │                   └── pom.properties
│   └── stale
│       └── extract-native.dependencies
└── test
    └── hello
        └── core_test.clj

14 directories, 9 files

project.cljを書き換え

cat project.clj
(defproject hello "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]]
  :main hello.core)


lein repl で 実行。lein --help すると "Start a repl session either with the current project or standalone."

$ lein repl
nREPL server started on port 52522 on host 127.0.0.1 - nrepl://127.0.0.1:52522
REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_65-b17
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

hello.core=> fo #Tabで候補が表示される
foo      for      force    format
hello.core=> (foo "delaemon")
delaemon Hello, World!
nil

valgrind on Fedora22

Valgrind is an instrumentation framework for building dynamic analysis tools.
Valgrind Home

インストール

$ sudo dnf install valgrind

メモリリーク検出

$ valgrind --leak-check=full ./fib
==4784== Memcheck, a memory error detector
==4784== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4784== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4784== Command: ./fib
==4784==
832040
==4784==
==4784== HEAP SUMMARY:
==4784==     in use at exit: 0 bytes in 0 blocks
==4784==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4784==
==4784== All heap blocks were freed -- no leaks are possible
==4784==
==4784== For counts of detected and suppressed errors, rerun with: -v
==4784== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

ヒーププロファイラ

$ valgrind --tool=massif ./fib
==4805== Massif, a heap profiler
==4805== Copyright (C) 2003-2013, and GNU GPL'd, by Nicholas Nethercote
==4805== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4805== Command: ./fib
==4805==
832040
==4805==
$ ls -la massif.out.4805
-rw------- 1 dela dela 144 Feb  8 08:48 massif.out.4805
$ cat massif.out.4805
desc: (none)
cmd: ./fib
time_unit: i
#-----------
snapshot=0
#-----------
time=0
mem_heap_B=0
mem_heap_extra_B=0
mem_stacks_B=0
heap_tree=empty

コールグラフ

$ valgrind --tool=callgrind ./fib
==4837== Callgrind, a call-graph generating cache profiler
==4837== Copyright (C) 2002-2013, and GNU GPL'd, by Josef Weidendorfer et al.
==4837== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4837== Command: ./fib
==4837==
==4837== For interactive control, run 'callgrind_control -h'.
832040
==4837==
==4837== Events    : Ir
==4837== Collected : 45872890
==4837==
==4837== I   refs:      45,872,890
$ ls -la callgrind.out.4837
-rw------- 1 dela dela 12618 Feb  8 08:49 callgrind.out.4837

perf on Fedora22

perf: Linux profiling with performance counters
Perf Wiki

インストール

$ sudo dnf isntall perf

てきとうなコードを用意

$ gcc fib.c -o fib

イベント数を取得

$ perf stat ./fib
832040
failed to read counter stalled-cycles-frontend
failed to read counter stalled-cycles-backend

 Performance counter stats for './fib':

         11.102711      task-clock (msec)         #    0.967 CPUs utilized
                 2      context-switches          #    0.180 K/sec
                 0      cpu-migrations            #    0.000 K/sec
                48      page-faults               #    0.004 M/sec
        19,328,246      cycles                    #    1.741 GHz
   <not supported>      stalled-cycles-frontend
   <not supported>      stalled-cycles-backend
        46,303,730      instructions              #    2.40  insns per cycle
         9,527,011      branches                  #  858.080 M/sec
             5,258      branch-misses             #    0.06% of all branches

       0.011485366 seconds time elapsed

解析実行

$ perf record ./fib
832040
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data (47 samples) ]

解析ファイルが作られる

$ ls -la
-rw------- 1 dela dela 14944 Feb  6 11:27 perf.data
-rw------- 1 dela dela 47080 Feb  6 11:16 perf.data.old

解析結果を見る

$ perf report

Samples: 68  of event 'cycles', Event count (approx.): 20695033
Overhead  Command  Shared Object      Symbol
  94.16%  fib      fib                [.] fib
   2.22%  fib      [kernel.kallsyms]  [k] _raw_spin_lock
   1.54%  fib      [kernel.kallsyms]  [k] filemap_map_pages
   1.49%  fib      [kernel.kallsyms]  [k] async_page_fault
   0.27%  fib      [kernel.kallsyms]  [k] bad_range
   0.17%  fib      [kernel.kallsyms]  [k] run_timer_softirq
   0.08%  fib      [kernel.kallsyms]  [k] __remove_hrtimer
   0.06%  fib      [kernel.kallsyms]  [k] native_write_msr_safe

Build coreutils on Fedora22

Fedora22上にcoreutilsをビルドする。

コードを用意して、./bootstrapを実行すると、必要なパッケージがわかる

git clone git@github.com:coreutils/coreutils.git
cd coreutils
./bootstrap
./bootstrap: line 424: autoconf: command not found
./bootstrap: Error: 'autoconf' not found
./bootstrap: line 424: automake: command not found
./bootstrap: Error: 'automake' not found
./bootstrap: line 424: autopoint: command not found
./bootstrap: Error: 'autopoint' not found
./bootstrap: line 221: bison: command not found
./bootstrap: Error: 'bison' not found
./bootstrap: line 221: gperf: command not found
./bootstrap: Error: 'gperf' not found
./bootstrap: line 424: makeinfo: command not found
./bootstrap: Error: 'makeinfo' not found
./bootstrap: line 221: patch: command not found
./bootstrap: Error: 'patch' not found

必要なものをインストール

sudo dnf install automake bison gperf patch gettext-devel texinfo

configure, make

./configure --prefix=${HOME}/bin/coreutils
make CFLAGS='-g'
make install

prefixで指定したディレクトリにビルドされたものが配置されてる

/home/user/bin/coreutils/bin/ls

ls以外のコマンドも出来てる。
次回はからは必要なものだけ make src/xxxで良い。

nginx build form source on Fedora23 Server (OSX VirtualBox)

OSX VirtualBox上のまっさらなFedora23Serverにnginxをsourceからビルド

最短距離

$ sudo dnf install git gcc pcre-devel zlib-devel openssl-devel
$ git clone https://github.com/nginx/nginx.git
$ cd nginx
$ ./auto/configure --with-openssl=/usr/lib64/openssl
$ make
$ sudo make install
$ sudo chmod +x /usr/local/nginx/sbin/nginx
$ sudo /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.9.10
built by gcc 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
configure arguments: --with-openssl=/usr/lib64/openssl
$ sudo firewall-cmd --permanent --add-service=http
success
$ sudo firewall-cmd --permanent --add-port=80/tcp
success
$ sudo systemctl restart firewalld
$ sudo firewall-cmd --list-all
FedoraServer (default, active)
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client http https ssh
  ports: 80/tcp
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

以下、遭遇したエラー

gccがない
$ ./auto/configure
checking for OS
 + Linux 4.2.3-300.fc23.x86_64 x86_64
checking for C compiler ... not found

./auto/configure: error: C compiler cc is not found

gccを入れる

$ sudo dnf install gcc
pcreがない
$ ./auto/configure
~ 省略
checking for PCRE library ... not found
checking for PCRE library in /usr/local/ ... not found
checking for PCRE library in /usr/include/pcre/ ... not found
checking for PCRE library in /usr/pkg/ ... not found
checking for PCRE library in /opt/local/ ... not found

./auto/configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

pcreを入れる

$ sudo dnf install pcre-develop
zlibがない
$ ./auto/configure
~ 省略
checking for zlib library ... not found

./auto/configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.

zilbを入れる

$ sudo dnf install zlib-devel
opensslがない
$ ./auto/configure
~ 省略

Configuration summary
  + using system PCRE library
  + OpenSSL library is not used
  + using builtin md5 code
  + sha1 library is not found
  + using system zlib library

opensslを入れる、オプション指定する

$ sudo dnf install openssl-devel
$ ./auto/configure --with-openssl=/usr/lib64/openssl
port 80に接続できない

firewalldで許可する

$ sudo firewall-cmd --permanent --add-service=http
success
$ sudo firewall-cmd --permanent --add-port=80/tcp
success
$ sudo systemctl restart firewalld
$ sudo firewall-cmd --list-all
FedoraServer (default, active)
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client http https ssh
  ports: 80/tcp
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

Scala Play activator on OSX

久しぶりにScala Play環境作ったらactivator というものが出てきたらしい。

"Typesafe Activator は activator ui と activator new という 2つのコマンドを追加するカスタム版の sbt だ。 つまり、activator は sbt のスーパーセットであると言える。"
始める sbt — Typesafe Activator (sbt を含む) のインストール

あ、はい。

以下を見ながらすすめた。
https://www.playframework.com/documentation/ja/2.3.x/Installing

javaのバージョン確認
Download | The Scala Programming Language

[dela@MacBook-Air dela] javac -version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
javac 1.6.0_65
[dela@MacBook-Air dela] java -version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)

Scala 2.11.7はjdk1.6以上が必要。だから大丈夫な、はず。更新はあとでやろうと思う。

brew installで最新がインストールされる。

[dela@MacBook-Air dela] brew info scala
scala: stable 2.11.7 (bottled), devel 2.12.0-M1
Scala programming language
http://www.scala-lang.org/
/usr/local/Cellar/scala/2.11.7 (46 files, 31M) *
  Poured from bottle
From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/scala.rb
==> Options
--with-docs
	Also install library documentation
--with-src
	Also install sources for IDE support
--devel
	Install development version 2.12.0-M1
==> Caveats
To use with IntelliJ, set the Scala home to:
  /usr/local/opt/scala/idea

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

[dela@MacBook-Air dela] brew install scala
==> Downloading https://homebrew.bintray.com/bottles/scala-2.11.7.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring scala-2.11.7.yosemite.bottle.tar.gz
==> Caveats
To use with IntelliJ, set the Scala home to:
  /usr/local/opt/scala/idea

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/scala/2.11.7: 46 files, 31M

activatorをダウンロードしてパスを通す。
Build Reactive Applications with Typesafe Activator | @typesafe

export PATH=$PATH:/path/to/activator-dist-1.3.7

activatorコマンドの確認

[dela@MacBook-Air dela] activator -help
Usage: activator <command> [options]

  Command:
  ui                 Start the Activator UI
  new [name] [template-id]  Create a new project with [name] using template [template-id]
  list-templates     Print all available template names
  -h | -help         Print this message

  Options:
  -v | -verbose      Make this runner chattier
  -d | -debug        Set sbt log level to debug
  -mem <integer>     Set memory options (default: , which is -Xms1024m -Xmx1024m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m)
  -jvm-debug <port>  Turn on JVM debugging, open at the given port.

  # java version (default: java from PATH, currently java version "1.8.0_65")
  -java-home <path>  Alternate JAVA_HOME

  # jvm options and output control
  -Dkey=val          Pass -Dkey=val directly to the java runtime
  -J-X               Pass option -X directly to the java runtime
                     (-J is stripped)

  # environment variables (read from context)
  JAVA_OPTS          Environment variable, if unset uses ""
  SBT_OPTS           Environment variable, if unset uses ""
  ACTIVATOR_OPTS     Environment variable, if unset uses ""

In the case of duplicated or conflicting options, the order above
shows precedence: environment variables lowest, command line options highest.

Scala Play アプリを新規作成して、activatorコンソールを起動する。

[dela@MacBook-Air develop] activator new my-first-app play-scala
[dela@MacBook-Air develop] cd my-first-app/
[dela@MacBook-Air my-first-app] activator
#省略
[error] java.lang.UnsupportedClassVersionError: org/webjars/WebJarExtractor$Cache : Unsupported major.minor version 51.0

jdkを更新。使おうとしてるバージョンに合わせる。
Java SE - Downloads | Oracle Technology Network | Oracle
ダウンロードして.zshrcのJAVA_HOMEを以下に変更

export JAVA_HOME=`/usr/libexec/java_home -v 1.8`

activatorコンソールを再起動する。

[dela@MacBook-Air my-first-app] activator
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
[info] Loading project definition from /Users/dela/Documents/develop/scala/my-first-app/project
[info] Set current project to my-first-app (in build file:/Users/dela/Documents/develop/scala/my-first-app/)
[my-first-app] $

アプリを起動。初回は相変わらずすごく時間かかる

[my-first-app] $ run
[info] Updating {file:/Users/dela/Documents/develop/scala/my-first-app/}root...
[info] Resolving jline#jline;2.12.1 ...
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-server_2.11/2.4.6/play-server_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-server_2.11;2.4.6!play-server_2.11.jar (847ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-netty-server_2.11/2.4.6/play-netty-server_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-netty-server_2.11;2.4.6!play-netty-server_2.11.jar (539ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-jdbc_2.11/2.4.6/play-jdbc_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-jdbc_2.11;2.4.6!play-jdbc_2.11.jar (430ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-cache_2.11/2.4.6/play-cache_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-cache_2.11;2.4.6!play-cache_2.11.jar (426ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-ws_2.11/2.4.6/play-ws_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-ws_2.11;2.4.6!play-ws_2.11.jar (651ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play_2.11/2.4.6/play_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play_2.11;2.4.6!play_2.11.jar (1459ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-iteratees_2.11/2.4.6/play-iteratees_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-iteratees_2.11;2.4.6!play-iteratees_2.11.jar (553ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-json_2.11/2.4.6/play-json_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-json_2.11;2.4.6!play-json_2.11.jar (552ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-netty-utils/2.4.6/play-netty-utils-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-netty-utils;2.4.6!play-netty-utils.jar (419ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-functional_2.11/2.4.6/play-functional_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-functional_2.11;2.4.6!play-functional_2.11.jar (438ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-datacommons_2.11/2.4.6/play-datacommons_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-datacommons_2.11;2.4.6!play-datacommons_2.11.jar (426ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-jdbc-api_2.11/2.4.6/play-jdbc-api_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-jdbc-api_2.11;2.4.6!play-jdbc-api_2.11.jar (424ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-test_2.11/2.4.6/play-test_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-test_2.11;2.4.6!play-test_2.11.jar (431ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-specs2_2.11/2.4.6/play-specs2_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-specs2_2.11;2.4.6!play-specs2_2.11.jar (424ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-omnidoc_2.11/2.4.6/play-omnidoc_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-omnidoc_2.11;2.4.6!play-omnidoc_2.11.jar (2169ms)
[info] downloading https://repo1.maven.org/maven2/com/typesafe/play/play-docs_2.11/2.4.6/play-docs_2.11-2.4.6.jar ...
[info] 	[SUCCESSFUL ] com.typesafe.play#play-docs_2.11;2.4.6!play-docs_2.11.jar (1464ms)
[info] Done updating.

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

[info] Compiling 7 Scala sources and 1 Java source to /Users/dela/Documents/develop/scala/my-first-app/target/scala-2.11/classes...
[info] 'compiler-interface' not yet compiled for Scala 2.11.6. Compiling...
[info]   Compilation completed in 16.004 s
[info] - play.api.Play - Application started (Dev)

activator ui 使ってみた。

[dela@MacBook-Air my-first-app] activator ui

脇のメニューから大体できること想像がつく。サーバーのコードをブラウザから変更できそう。
使ってみないと判断できないけど、思想は進んでる。
f:id:delaemon:20151220234633p:plain