esオペレーティングシステムの使い方


はじめに

バージョン0.0.12以降のesオペレーティングシステムでは、カーネルが起動するとSVGA画面上でコマンドラインシェルが起動するようになっています。ここではesオペレーティングシステム の使い方を簡単に紹介します。

esオペレーティングシステムの起動

esオペレーティングシステムがインストールされたPCの電源を入れると、次のような文字がSVGA画面上に表示されます。

esjs file/shell.js
alloc count: 2400
yypase() ok.
% 

esオペレーティングシステムではカーネルが実行を始めると、イベントマネージャー(eventManager.elf)とコンソールマネージャー(console.elf)を起動しています。イベントマネージャーはキーボードやマウスからの入力をイベントとして記録して外部のプログラムから利用できるようにするサービスを提供するユーザープロセスです。コンソールマネージャーはイベントマネージャーからキーボードイベントを取得して入力された文字のストリームに変換したり、SVGA画面上に文字列を表示するサービスを提供するユーザープロセスです。

基本的なサービスの起動を終えると、カーネルはECMAScriptインタープリタ(esjs.elf)を起動してコマンドラインシェルプログラム(shell.js)の実行を開始します。コマンドラインシェルはコンソールマネージャーのサービスを利用してユーザーにコマンドベースの対話環境を提供します。esオペレーティングシステムでは処理速度の違いを除けば、コマンドラインシェルプログラムやテキストエディタのような従来はC言語やC++言語で書かれていたようなプログラムもECMAScriptを使って簡単に記述することができます。

コマンド

コマンドラインシェルから呼び出すことができるプログラムには以下のようなものがあります。(今後、さらに追加していきます。) コマンドの中には、SqueakのようにC言語で記述されているものも、editコマンドのようにECMAScriptで記述されているものもあります。

コマンド名 内容
cat [file ...] 標準出力にファイルを表示する
cd [dir] カレントディレクトリをdirに設定する
clear 図形描画用のキャンバスをクリアする
date [-u] 現在の日時を表示する
echo [arg ...] 引数を標準出力に表示します
edit [file] Unixのedライクなラインテキストエディタ
exit コマンドラインシェルを終了する(shellの組み込みコマンド)
figure CanvasRenderingContext2Dインターフェイスを用いてSVGA画面に描画するデモスクリプト
ls [dir ...] ディレクトリの一覧を表示する
rm [file ...] ファイルを削除する
squeak Squeak (Smalltakプログラミング環境)

名前空間

lsコマンドを引数なしで実行すると、カレントディレクトリ内にあるオブジェクトの名前の一覧が表示されます。

% ls
device
network
class
interface
file 
% 

esオペレーティングシステムでのカレントディレクトリは名前空間の任意の位置にcdコマンドを使って設定することができます。起動時にはカレントは名前空間のルートに設定されています。deviceの名前空間にカレントを移動してデバイスの一覧を表示してみます。

% cd device
% ls
rtc
cga
beep
framebuffer
cursor
keyboard
mouse
ata
floppy
loopback
soundInput
soundOutput
ethernet
event
console
%  

esの名前空間規約で示したようなデバイスのほかに、eventとconsoleというデバイスがあることがわかります。これらはそれぞれイベントマネージャーとコンソールマネージャーによって動的に名前空間に登録されたデバイスです。

cdコマンドを引数なしで呼び出すと名前空間のルートにカレントが戻ります。

% cd
% ls
device
network
class
interface
file 
% 

file名前空間にはローカルのディスクがマウントされています。lsコマンドの引数にfileを指定して一覧を表示してみます。

% ls file
es.ldr
es.img
eventManager.elf
console.elf
esjs.elf
shell.js
cat.js
cd.js
date.js
echo.js
edit.js
ls.js
sazanami-mincho.ttf
squeak.elf
SqueakV3.sources
Squeak3.7-5989-full.changes
Squeak3.7-5989-full.image
% 

プロンプトからsqueakとタイプしてEnterキーを押せばSqueakが起動します。Squeakの実行中は、コンソールサービスは一時的に中断して、squeakがイベントマネージャー やフレームバッファに直接アクセスしてグラフィカルなユーザーインターフェイスを提供します。デスクトップを左クリックしてworldメニューを表示しquitを選択すれば、またコンソールサービスが再開されてコマンドラインシェルに戻ってきます。

% squeak
% 

コマンドラインシェルの組み込みコマンドexitを実行するとコマンドラインシェルが終了し、shell.jsを実行していたECMAScriptインタープリタesjs.elfも終了します。esカーネルは最初に起動したesjs.elfが終了するとPCをシャットダウンします。つまり、プロンプトでexitとタイプしてEnterキーを押せばPCの電源を切ることができます。

% exit

ここまでが簡単なesオペレーティングシステムの使い方です。

esオペレーティングシステムでのプログラミング

esオペレーティングシステムのカーネル本体やELF形式のバイナリプログラムのプログラミングを行うためには、少なくとも現状ではFedoraなどでGCCのクロス開発環境を用意したりといった面倒な準備が必要になりますが、ECMAScriptのプログラムならesオペレーティングシステム上で直接編集しながら作っていくことができます。試しにdateプログラムの内容を見てみましょう。

% cat file/date.js
var date = new Date();
var str = date.toString();
stdout.write(str + '\n', str.length + 1);
% 

標準のECMAScriptには規定されていないオブジェクトstdoutが使われていることがわかります。shell.js用のプログラムでは以下のようなオブジェクトを使うことができます。

オブジェクト名 対応するインターフェイス(クラス) 内容
System ICurrentProcess カレントプロセス
stdin IStream 標準入力
stdout IStream 標準出力
stderr IStream 標準エラー出力
root IContext ルート名前空間
cwd IContext カレントディレクトリ
classStore IClassStore クラスストア
path Array 実行ファイルのあるディレクトリへのパス名の配列

esjsはIDLで定義したインターフェイスをスクリプトから呼び出すことができるように実装されています。たとえば、Systemという名前のオブジェクトからはカレントプロセスのICurrentProcessesインターフェイス が提供するメソッドを呼び出すことができます。

ただし、IDLで定義されたインターフェイスを利用するときには、いくつか注意すべき点もあります。ECMAScriptではC言語のように変数aのアドレスを明示的に関数に渡すと言うことができません。一方、IStreamのreadメソッドは次のようにIDLで定義されています。


int read([out, size_is(count)] void* dst, int count);

そこでesjsインタープリタは、IStreamのreadメソッドのようにIDLの定義out属性の付いた引数のあるメソッドはout属性のついた引数 がメソッドの戻り値となるように変換しています。したがって、標準入力から1文字読み込むためには、次のように書きます。


var c = stdin.read(1);

この例では戻り値cは長さ0か1のstring型の値になります。ただし、out属性付きの引数を複数もつメソッドでは2番目以降の引数に設定された内容は呼び出し先からは調べられません。

あるインターフェイスから別のインターフェイスを(内部的にはqueryInterfaceを使って)取り出したいときには、以下のように記述します。


unknown = iter.next();        # unkown は IInterface のオブジェクト
file = IFile(unknown);        # IFile インターフェイスを取り出す

これは、次のように記述しても同じです。


file = new IFile(unknown);    # IFile インターフェイスを取り出す
  または
file = unknown.queryInterface("0325f4e6-25db-11db-9c02-0009bf000001");

また、ECMAScriptではC++のように関数名をオーバーロードして使うことができません。ECMAスクリプトでは引数の数が足りない場合にはundefined型の値が自動的に渡されますし、型が合わない場合にはインタープリタ側で自動的に型変換を行おうとします。そこで、IDL定義でメソッド名がオーバーロードされていた場合にはesjsは最初に定義されたメソッドを呼び出します。

ECMAScriptのようにガベージコレクタが動いている言語ではメモリの解放はインタープリタや仮想マシンに完全に任せることができますが、システムリソースの解放はかならずしもインタープリタ側に任せられない場合があります。それはガベージコレクションの発動するタイミングは一般的にはシステムリソースが不要になったタイミングと連動しないためです。esjsではそのような場合、明示的にreleaseメソッドを呼び出してシステムリソースを解放することができます。


file.release();        # IFile インターフェイスを解放する。

esjsの現在の実装では簡単な世代GCだけで資源管理を行っているので、上記のようにreleaseを明示的に呼び出さないとプロセスのオブジェクト表がすぐにいっぱいになってしまう場合があります。将来のバージョンでは参照数管理などと組み合わせてこのような制約を取り除いていく予定です。

そのほか、IDLでインターフェイスを定義する際には、メソッド名にECMAScriptで引数の数を示すプロパティと重なるlengthという名前は使わない、引数名にECMAScriptの引数リストと重なるargumentsという名前は使わない、といった点に は注意する必要があります。

実際に小さなファイルを編集してみたいときには、editコマンドを利用することができます。

% edit file/date.js
3
1,$p
var date = new Date();
var str = date.toString();
stdout.write(str + '\n', str.length + 1);
q
% 

このeditコマンドは参考文献[1, 2]で紹介されているeditプログラムをesjsに移植したものです。もともとはそれぞれRatfor, Pascalで書かれていたプログラムです。ウェブブラウザ用の言語のようなイメージもあるECMAScriptですが、実際には例外や正規表現をサポートした優れた汎用プログラミング言語であることが判るかと思います。

【注意】ECMAScript 第3版との互換性について

esjs バージョン0.1.1では、ECMAScript 第3版の仕様と比較した場合、以下のような違いがあります:

参考文献

[1]  B. W. Kernighan and P. J. Plauger, Software Tools, Addison-Wesley, 1976. (翻訳 - 木村泉訳, ソフトウェア作法, 共立出版, 1981年)
[2]  B. W. Kernighan and P. J. Plauger, Software Tools in Pascal, Addison-Wesley, 1981.

[esオペレーティングシステムのホームページに戻る]


Copyright © 2007
Nintendo Co,. Ltd.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Nintendo makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

SourceForge.jp