Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
Opgaverne til denne gang indeholder (om muligt) endnu flere ting der
kan gaa galt. Saa hvis du sidder fast i noget, saa lad vaere med at
bruge en masse tid paa det! Lav hellere en posting paa nyhedsgruppen,
og proev at komme videre. Hvis du sidder helt fast i LOCUM, saa gaa
videre med JSpec-opgaverne.
(0) LOCUM
LOCUM (Langage à Objets en C Ultimement Moche) er en slags projektion
af et simpelt OO sprog ned paa C. Der er klasser og objekter, og man
kan lave virtuelle kald. Men man skal selv saette det hele sammen
(man kunne lave en "Java2LOCUM", men det har jeg ikke haft tid til :-).
Filen "point.h" er et eksempel paa hvordan man definerer en klasse.
Foerst erklaeres objektet, derefter erklares dets vtable som skal
indeholde en pointer til klassen, pointere til metoderne erklaeret i
superklassen, og endelig de metoderne fra den lokale klasse.
(Sammenlign med ObjectVTable fra "locum.h".) Desuden erklaeres det
objekt der indeholder klassen, og den struktur der indeholder
objektets vtable. Endelig er der en funktion der initialiserer
klassen, og som man skal huske at kalde foer man bruger den foerste
gang.
Filen "point.c" erklarer blot de faktiske strukturer, og inkluderer en
seperat fil hvor metoderne er erklaerede. Der er for eksempel en
"equals" metode der teste om et andet objekt er et point og hvis saa
om koordinaterne er de samme. Der er ogsaa en "toString" og et par
metode til at tilgaa tilstanden. Endelig er der "init_Point" der
stopper de rigtige metoder ind i klassens vtable. (Bemaerk at
f.eks. metoden "Object_getClass" er nedarvet.)
Filen "format.c" indeholder en formatterings-funktion, og "test.c"
laver en lille test at den.
For at compile test-programmet:
gcc -Wall locum.c locum_lib.c test.c point.c format.c -o test
Proev at koere det, og at forstaa hvad der foregaar paa runtime.
(Brug evt. gdb til dynamisk at foelge med i udfoerslen af
programmet.)
Format eksemplet er klargjort til at kunne blive specialiseret med
Tempo (ved at bruge filen "format.c"). Faa det til at specialisere,
kig paa hvad der kommer af warnings (saa du ved hvad der ikke goer
noget) og kig paa resultatet. Forstaa hvad der skete.
(1) Implementer power-eksemplet i LOCUM - se appendix for en Java
version. Analyser det for en kontekst hvor den binaere operator
er enten addition eller multiplikation. Faa det til at
specialisere med statisk operator og dynamisk base-vaerdi.
Pitfalls:
- Der er mange ting der kan gaa galt, saa det er bedst at foelge
den kode-stil der er i format-eksemplet.
- "ERROR (AT2SPEC 41): function body must be a block": se point_methods.c
(2) Gen-analyser (1) med dynamisk operator og statisk base-vaerdi.
Faa det til at specialisere.
(3) Specialiser Java-versionen af power med JSpec.
Lav f.eks. en fil "Pow.jspec" med foelgende indhold
= module "Pow"
= entry_point {int Power.raise(int base)}
= entry_point_signature {S D}
= main_classes {Power Binary Mul Add}
= specialized_entry_point "raise_spec"
= compile_during_weave 1
"Pow" bruges som basis-navn for f.eks. color-filerne. Entry point
angives af to gange: da der jo er overloading paa metoder skal man
angive hele signaturen. Bindingstiden angives i
"entry_point_signature" som ogsaa angiver bindings-tiden af "this"
objektet. "main_classes" angiver de klasser der skal specialiseres
fra/til. (Den sidste switch faar JSpec til at gencompile
Java-programmet med den specialiserede kode.)
For at taende for inlining kan man bruge:
= inlining 1
men bemaerk at det kun virker hvis alle fields er public.
Lav saa en fil "_JSpec_Context" i stil med foelgende:
import fr.irisa.compose.jspec.StaticValue;
import fr.irisa.compose.jspec.DynamicValue;
public class _JSpec_Context {
public static Power _this;
public static int base;
// main metoden skal kalde main i en klasse der koerer programmet
public static void main( String argv[] ) {
Main.main( argv );
}
public static void setAnalysisContext() {
BinOp bin = StaticValue.get_boolean()?(BinOp)new Add():(BinOp)new Mul();
_this = new Power(bin,StaticValue.get_int());
base = DynamicValue.get_int();
}
public static void setSpecializationContext() {
_this = new Power(new Mul(),3);
}
}
De to fields "_this" og "base" svarer til parametrene til
entrypoint. De _skal_ have de samme navne som dem der blev angivet
med "entry_point". For at compile _JSpec_Context.java skal der
bruges en Main.java der bruger all de klasser der er relevante for
specialiseringen, f.eks.:
public class Main {
public static void main(String argv[]) {
System.out.println(new Power(new Mul(),(new Power(new Add(),2)).raise(3)).raise(4));
}
}
Slet derefter alle .class filer (JSpec bruger den aeldgamle JDK 1.0
som ikke kan lide de nyeste Java-compilere.), og koer:
~ups/JSpec/jspec/bin/jspec -javac
Derefter skal det oversaettes til C kode, brug:
~ups/JSpec/jspec/bin/jspec -preprocess Pow
(Hvis du overskrider din disk-kvota, saa faa en stoere en :-)
Bemaerk at config.sml ogsaa bliver genereret paa nuvaerende
tidspunkt, saa hvis du vil aendre i options i Pow.jspec, saa er du
noedt til at starte forfra herfra igen. Alternativt kan du rette
direkte i den genererede fil
For at analysere programmet, brug
~ups/JSpec/jspec/bin/jspec -analyze Pow
Det tager et paent stykke tid (f.eks. 10 minutter - saa er du
advaret!) Hvis alt gaar vel, saa specialiser
~ups/JSpec/jspec/bin/jspec -specialize Pow
Det tager ogsaa noget laengere tid end du er vant til, men ikke saa
lang tid som at analysere.
Hvis der opstaar et problem undervejs, saa kig hurtigt paa om du kan
overskue hvad der gik galt, ellers lav en posting paa nyhedsgruppen.
Alle filerne ligger i det subdirectory der hedder "jwd". Kig gerne
paa f.eks. bta.color eller at.color filerne for at se hvad der sker.
Men koncentrer dig om de relevante funktioner - der er virkelig
meget "stoej" i filerne.
(4) Som (2), bare med programmet fra (3).
(5) Genimplementer format-eksemplet fra (1) i Java, og specialiser det
med JSpec. Husk: jo mindre fancy, jo stoerre er chancen for at
det kommer igennem. F.eks. er det en daarlig ide at bruge
avancerede operatorer saasom "+="...
--------------------------------------------------------------------------------
APPENDIX: power i Java
--------------------------------------------------------------------------------
public abstract class BinOp {
public abstract int apply(int x, int y);
public abstract int neutral();
}
public class Mul extends BinOp {
public int apply(int x, int y) {
return x*y;
}
public int neutral() {
return 1;
}
}
public class Add extends BinOp {
...
}
public class Power {
BinOp op;
int exp;
public Power(BinOp op, int exp) {
this.op=op; this.exp=exp;
}
public int raise(int base) {
int r=op.neutral();
int e=this.exp;
while(e-->0)
r=op.apply(r,base);
return r;
}
}
--------------------------------------------------------------------------------