Fase terakhir dalam model compiler adalah code generator. Code generator sebagai input yang
representasi lanjutan dari source program dan hasil sebagai output equivalent dgn target
program. Sesuai gambar 9.1. teknik pembangkit dalam bab ini digunakan sebagai tahap optimasi
sebelum pembangkit code, hal ini disebut compiler “optimizing”.
Gambar. 9.1.
Tujuan secara tradisional membuat pembangkit code secara mencukil. code Output harus benar
dan berkualitas, berarti harus efektiv pengguanan resource dari target mesin. Lebih dari itu
pembangkit code dapat dijalankan penterjemah secara efektif.
Masalah untuk membangkitkan code optimal secara matematika tdk dapat dijalankan. Secara
praktis harus berisi cara-cara heuristik yg membangkitkan produk, tetapi tdk perlu mendapati
code optimal. Pemilihan kode heuristic ini perlu dan dirancang dgn algoritma pembangkit code
yang lebih mudah dan lebih cepat dgn algoritma yg diprkirakan secara serentak.
Target program
Output dari pembangkitan code adalah target program. Output ini mungkin memiliki bentuk
yang berbeda: bahasa mesin absolut, bahasa mesin relocatable, atau bahasa assembly.
Membuat program bahasa mesin sebagai output memiliki pengembangan yang ditempatkan di
lokasi memori yg tetap dan dieksekusi segera. Program yg kecil dapat di-compil dan dieksekusi
dgn cepat.
Membuat program bahasa mesin yg ditempatkan kembali (modul objek) sebagai output
menizinkan sub-program di-compile secara terpisah. Pengaturan modul objek yg ditmpatkan
kembali bisa di-link bersamaan dan diproses untuk dieksekusi.
Membuat program bahasa assembli sebagai output membuat proses pembangkitan kode mudah.
Kita bisa mengembangkan instruksi simbolik dan menggunakan fasilitas-fasilitas macro dalam
pembangkitan kode. Harga terbayarkan tahapan rakitan setalah pembangkitan kode. Karena
membuat kode rakitan tidak bisa menduplikat tugas-tugas assembler, pilihan ini adalah alternativ
lain khususnya untuk mesin dgn memori yg kecil, dimana kompiler harus memakai pass lainnya.
Memory management
Pemetaan nama dalam source program ke alamat-alamat data objek di memory run-time
dilakukan bersama diujung akhir dan pembangkit code.
Jika kode mesin dibangkitkan, lebel di pernyataan tiga-alamat harus dikonversi ke instruksi
alamat. Proses ini dianalogikan seperti teknik ”backpatching”.
Instruction selection
Pengaturan instruksi dari target mesin menentukan kesulitan instruksi pilihan. Keseragaman dan
kelengkapan set instuksi adalah factor penting. Jika target mesin tidak mendukung setiap tipe
data yang seragam. Kecepatan instruksi dan idiom mesin adalah faktor penting lainnya.Kualitas
dari kode pembangkit ditentukan oleh speed dan size-nya. Contoh, setiap statement tiga-alamat
dgn bentuk x:=y+z, bisa diubah kedlm urutan code.
Mov y,R0 /* proses y ke register R0 */
Add z,R0 /* tambah z ke R0 */
Mov R0,x /* simpan R0 ke x */
Sayangnya, statement-statement kode pembangkit seperti ini sering salah kode prosedur. Contoh,
statement
a := b + c
d := a + e
akan diterjemahkan kedalam
MOV b,R0
ADD c,R0
MOV R0,a
MOV a,R0
ADD e,R0
MOV R0,d
Pada statement keempat di-redundant, begitu juga yg ketiga jika a bukan kelanjutan yg
digunakan.
Register allocation
Perintah-perintah menyertakan operasi register biasanya untuk memperpendek dan mempercepat
dari pada perintah-perintah tersebut menyertakan operasi di memori. Menggunakan register
sering dibagi lagi kedalam 2 sub-masalah:
- Selama register allocation, kita pilih variabel yang akan kita letakkan di register didalam
sebuah program.
- Kemudian saat fase register assignment, kita angkat register yang khusus itu yang akan
diletakkan variabel didalamnya.
Secara matematis, masalahnya adalah NP-complete. Maslahnya lebih rumit karena hardware
dan/atau operating system target mesin yg mungkin membutuhkan aturan register-usage tertentu
untuk diamati.
Mesin-mesin tertentu meminta register-pairs untuk beberapa operasi dan hasil. Contoh, pd mesin
IBM system/370
Instruction costs
Contoh:
1. instruksi MOV R0,R1 copy isi yg ada di register R0 ke register R1. insstruksi ini memiliki
nilai satu, sejak itu menempati satu kata dr memori.
2. instruksi ADD #1,R3 menambah constanta 1 ke isi dr register 3, dan memiliki nilai dua, sejak
konstanta 1 harus muncul di kata selanjutnya mengikuti instruksinya.
Structure-preserving transformations
Srtucture-preserving transformation yg utama pd basic blok adalah:
1. common subexpression elimination
2. dead-code elimination
3. renaming of temporary variables
4. interchange of two independent adjacent statements
Algebraic transformation
Transformation aljabar bisa digunakan untuk merubah set ekspresion yg dihitung oleh sebuah
basic blok kedalam set equivalent aljabar.
Contoh:
x:= x + 0
or
x:= x * 1
bisa dieliminasi dari block dasar tanpa mengganti set kalimat penghitungan itu. Operasi
eksponen pada statement
x:= y ** 2
biasanya permintaan fungsi call untuk diimplementasi. Dengan transformasi aljabar, statement
ini bisa diganti dgn murah, tapi statement equivalen
x:= y * y
Flow graphs
Kita bisa menambahkan informasi arah alur ke set basic blok yg dpt meningkatkan program
dengan membuat arah graph yg disebut flow graph. Node-node dr flow graph adlah basic blok.
Satu node dibedakan sebagai inisial; blok yg pertama adalah statement yang pertama.
Loops
Loop adalah kumpulan node-node dalm flow graph. Loop yg berisi tdk lain loop disebut inner
loop.
Kode generator sangat baik sekali digunakan untuk men-generate aplikasi-aplikasi database,
karena aplikasi database hampir memliki kode-kode yang sama (insert-update-delete-dsb) hanya
objeknya saja yang berbeda. Maka jika kita ingin membuat belasan aplikasi database dengan
objek yang berbeda, pembuatan kode generator dengan rancangan yang baik sangat layak untuk
dipertimbangkan.
Hanya sebagai contoh saja, Anda dapat mendownload kode generator yang kurang baik disini.
Walaupun kurang baik, tapi coba perhatikan apakah keistimewaanya?
Option Explicit
Mulai dari versi 1.1.2, Yii sudah dilengkapi dengan sebuah code generator berbasis Web yang
disebut Gii. Tool ini menggantikan tool sebelumnya yakni yiic shell yang berjalan di
command line. Di bagian ini, kita akan melihat bagaimana menggunakan Gii dan cara
meningkatkan(mengembangkan) kemampuan Gii untuk mendongkrak produktivitas
pengembangan.
1. Penggunaan Gii
Gii diimplementasi sebagai module dan harus digunakan di dalam aplikasi Yii. Untuk
menggunakan Gii, kita pertama-tama memodifikasi konfigurasi aplikasi sebagai berikut:
return array(
......
'modules'=>array(
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'masukkan password di sini',
// 'ipFilters'=>array(...a list of IPs...),
// 'newFileMode'=>0666,
// 'newDirMode'=>0777,
),
),
);
Pada kode di atas, kita mendeklarasi sebuah module bernama gii yang merupakan instance dari
kelas GiiModule. Kita juga menentukan sebuah password untuk module yang akan ditanyakan
ketika mengakses Gii.
Secara default, Gii diatur supaya hanya dapat diakses di localhost saja demi alasan keamanan.
Jika kita ingin membuatnya dapat diakses di komputer lain yang sudah dipercaya, kita dapat
mengaturnya di properti Gii::ipFilters seperti yang ditunjukkan di kode di atas.
Karena Gii bisa dihasilkan dan menyimpan file kode baru di dalam aplikasi yang sudah ada, kita
harus memastikan bahwa proses Web Server memiliki pengaturan izin(permission) yang benar.
Properti Gii:Module::newFileMode dan GiiModule::newDirMode mengatur bagaimana file dan
direktori baru harus dihasilkan.
Catatan: Gii disediakan hanya untuk sebagai tool untuk dalam tahap pengembangan. Oleh
karena itu, harap diinstal di komputer tempat pengembangan(development). Dikarenakan Gii
bisa menghasilkan file PHP baru di dalam aplikasi, kita harus lebih memperhatikan secara
khusus mengenai penanganan masalah keamanan (misalnya password, IP Filter).
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'gii'=>'gii',
'gii/<controller:\w+>'=>'gii/<controller>',
'gii/<controller:\w+>/<action:\w+>'=>'gii/<controller>/<action>',
...existing rules...
),
),
)
Gii dilengkapi dengan beberapa code generator(kode penghasil). Setiap code generator
bertanggung jawab untuk menghasilkan kode dengan jenis tertentu. Misalnya, untuk controller
generator menghasilkan sebuah kelas controller dengan beberapa skrip aksi view(action view);
model generator menghasilkan kelas ActiveRecord (rekaman aktif) sesuai tabel database yang
sudah ditentukan.
2. Meningkatkan Gii
Walaupun secara default, code generator yang dari Gii dapat menghasilkan kode yang sangat
powerful, kita sering perlu menyesuaikan code generator tersebut atau membuat yang baru
supaya sesuai dengan keperluan dan selera kita. Misalnya, kita ingin menghasilkan kode yang
menjadi gaya koding kita sendiri, atau kita ingin kode kita mendukung berbagai bahasa.
Semuanya dapat dilakukan dengan Gii secara mudah.
Gii dapat ditingkatkan dengan dua cara: mengubah templat kode(code template) yang sudah ada,
dan menulis code generator yang baru.
Gii mencari generator yang tersedia di dalam kumpulan direktori yang ditentukan oleh properti
GiiModule::generatorPaths. Ketika diperlukan kustomisasi, kita dapat mengatur properti ini
dalam konfigurasi aplikasi sebagai berikut,
return array(
'modules'=>array(
'gii'=>array(
'class'=>'system.gii.GiiModule',
'generatorPaths'=>array(
'application.gii', // sebuah alias path
),
),
),
);
Konfigurasi di atas menginstruksi Gii untuk mencari generator yang terletak di dalam direktori
dengan alias application.gii, sebagai tambahan bagi lokasi default system.gii.generators.
Dimungkinkan untuk memiliki dua generator dengan nama yang sama namun memiliki jalur
pencarian(search path) yang berbeda. Kalau terjadi, generator di dalam jalur yang sudah
ditentukan pada waktu awal di GiiModule::generatorPaths akan didahulukan.
Ini merupakan langkah termudah dan paling umum untuk mengembangkan Gii. Kita gunakan
sebuah contoh untuk memahami bagaimana mengkustomisasi templat kode. Misalkan kita ingin
mengkustomisasi sebuah kode yang dihasilkan oleh model generator.
Sekarang buka halaman code generator model. Klik di field Code Template. Kita akan melihat
sebuah dropdown list yang berisi direktori templat yang baru kita buat, compact. Akan tetapi,
jika kita memilih templat ini untuk menghasilkan kode, kita akan menjumpai sebuah error
dikarenakan kita belum meletakkan kode apapun ke dalam file templat di compact.
Di masing-masing templat kode, kita dapat mengakses beberapa variabel yang sudah
didefinisikan sebelumnya, seperti $labels di contoh di atas. Varaibel ini disediakan oleh
generator kode yang bersangkutan. Generator kode yang berbeda akan menghasilkan variabel-
variable yang berbeda di templat kode. Silahkan baca dengan teliti deskripsi di dalam templat
kode default.
Di dalam sub-bab beriktu, kita akan melihat bagaimana membuat sebuah generator baru dapat
menghasilkan kelas widget yang baru.
Membuat WidgetGenerator.php
File WidgetGenerator.php sebetulnya sangat sederhana. File ini hanya berisi kode berikut:
Di dalam kode di atas, kita menetapkan bahwa generator akan menggunakan kelas model yang
alias pathnya adalah application.gii.widget.WidgetCode. Kelas WidgetGenerator
diturunkan dari CCodeGenerator yang mengimplementasi berbagai fungsionalitas, termasuk
aksi(action) dari kontroller yang diperlukan untuk mengkoordinasi dengan proses penghasilan
kode.
Membuat WidgetCode.php
File WidgetCode.php berisi kelas model WidgetCode memiliki logika utama untuk
menghasilkan sebuah kelas widget berdasarkan input dari pengguna. Dalam contoh ini, kita
mengasumsi bahwa input yang akan diterima dari pengguna hanyalah nama kelas widget.
Tampilan WidgetCode akan seperti ini :
Kelas WidgetCode diturunkan dari CCodeModel. Seperti kelas model pada umumnya, sebuah
kelas dapat dideklarasi rules() dan attributeLabels() untuk melakukan validasi input dari
pengguna dan menyediakan label atribut. Harap diingat karena kelas dasar CCodeModel sudah
mendefinisikan beberapa peraturan(rules) dan label atribut, kita harus menggabungkan menjadi
aturan dan label baru di sini.
Metode prepare() akan menyiapkan kode untuk dihasilkan. Fungsi utamanya adalah
menyiapkan daftar dari objek-objek CCodeFile, yang masing-masing mewakili sebuah file kode
yang akan dihasilkan. Di dalam contoh kita, kita hanya perlu membuat sebuah objek CCodeFile
yang mewakili file kelas widget. Kelas widget yang baru akan dihasilkan di dalam direktori
protected/components. Kita memanggil metode CCodeFile::render untuk menghasilkan kode
sebenarnya. Metode ini menyertakan templat kode sebagai skrip PHP dan mengembalikan isi
yang di-echo sebagai kode.
Membuat views/index.php
<h1>Widget Generator</h1>
<div class="row">
<?php echo $form->labelEx($model,'className'); ?>
<?php echo $form->textField($model,'className',array('size'=>65)); ?>
<div class="tooltip">
Widget class name must only contain word characters.
</div>
<?php echo $form->error($model,'className'); ?>
</div>
Pada kode di atas, kita menampilkan sebuah form menggunakan widget CCodeForm. Di dalam
form ini, kita menampilkan field untuk mendapatkan input dari atribut className di
WidgetCode.
Ketika membuat form, kita dapat memanfaatkan dua fitur yang disediakan oleh
widgetCCodeForm. Yang satu untuk memasukkan tooltips, dan yang satu lagi untuk sticky input.
Jika pernah mencoba code generator default, Anda pasti akan menyadari bahwa ketika kita
meletakkan fokus pada satu input field, sebuah tooltip yang bagus akan tampil di sebelah field.
Efek seperti ini bisa didapatkan dengan mudah dengan menulis di sebelah input field sebuah div
yang kelas CSS nya adalah tooltip.
Pada beberapa field input, kita mungkin ingin mengingat nilai valid sebelumnya sehingga
pengguna tidak perlu memasukkannya lagi setiap kali ingin menggunakan generator untuk
menghasilkan kode. Contohnya adalah input field yang meminta nama kelas dasar kontroller
pada controller generator. Sticky field ini pada awalnya ditampilkan sebagai teks statik yang
disorot. Jika kita mengkliknya, mereka akan berubah menjadi input field yang mengambil
inputan pengguna.
Untuk mendeklarasi sebuah input field menjadi sticky, kita perlu melakukan dua hal.
Pertama, kita perlu mendeklarasi sebuah aturan validasi sticky untuk atribut model yang
bersangkutan. Misalnya, controllger generator default memiliki aturan bahwa atribut baseClass
dan actions menjadi sticky:
Kedua, kita akan menambah sebuah kelas CSS yang bernama sticky ke dalam div dari input
field dalam di tilik, seperti berikut ini:
Pembuatan templates/default/widget.php
}
}
Langkah ini mengakhiri proses pembuatan code generator yang baru. Kita dapat mengakses code
generator ini dengan segera melakui URL
http://hostname/path/to/index.php?r=gii/widget.