Salih hocam yazdığınız kod oldukça leziz teşekkür ederim :) Kodu görünce utancımdan yerin dibine girdim.
Alıntı:
> Yani bir dilimle bir size_t aynı belleği paylaşıyorlar. Dilimlerin arka planda iki üyeli bir tür olduklarını bildiğimize göre (önce bir size_t, sonra bir veri göstergesi) parcala.length aslında our_memory.length'in aynısı oluyor.
Alıntı:
> Öncelikle union'a ihtiyacın var mı? Çünkü bellek alanı olarak kullandığın devingen (dynamic) dizinin, zaten çift taraflı bir length özelliği var. Üstelik bunu kullanmışsın ve bence bir yansımasını kullanmaya gerek yok. Ayrıca bir kaç püf noktası ile birlikte daha güvenli bir ortam oluşturabiliriz...
Evet haklısınız ihtiyaç yok union ile erişmek hızlı olacaktır diye düşündüm ama yanılmışım.
Salih hocam bu yaptığınız ASCII çevirme olayı bana oldukça ilham verdi diyebilirim. Amacım bu MM sınıfını dilin memory si olarak kullanmaktı ama şuanda dile compile seçeneği eklemek için düşünüyorum.
Alıntı:
> Bir hata görüyorum: Başlangıçta 1024 bayt yer olduğu halde ondan daha büyük bir istek gelse bile belleği uzatmadan o isteği karşılıyorsun.
Bildiğim kadarıyla object.length += 400 gibi bir ifade belleği uzatıyor.
Salih hocam kodda biraz değişiklik yaptım ve şöyle bir hale soktum.
module main;
import std.conv, std.string, std.stdio;
import std.container;
import core.memory;
int main(string[] argv){
auto memory = new MEM(8);
/*
Her programın üstüne RhodeusScript imzasını çakmak hoş olur diye düşündüm.
*/
memory.memWrite("RhodeusScript");
/*
Burada dizi üzerinde int boyutunda bir yer açıp programımızın tanımlamalarının hangi offsetten başladığının bilgisini tutuyoruz.
Örneğin string tanımlanmış bu stringin header kısmında önceden tanımlanmış olması gerekiyor
*/
auto defs = memory.memReserveAddress();
/*
Burada dizi üzerinde int boyutunda bir yer açıp programımızın hangi offsetten başladığının bilgisini tutuyoruz.
*/
auto program = memory.memReserveAddress();
memory.memLoadString("0.0.1");//Version
/*Definitions*/
memory.memSetAddress(defs);
memory.memLoadString("variable");
/*Our Program*/
memory.memSetAddress(defs);
memory.memLoadBytes(cast(ubyte[]) [0x90, 0x90, 0x90, 0x90, 0xC3]);
/*
memLoadString gibi kısımlar artık birer hayal. Güzel bir sistem kurulabilir bunların saklanması için
hem belkide bu esnada RhS nin nesne sistemi için güzel bir sistem kurgulanabilir
*/
memory.toString.writeln();
while(1){
}
return 0;
}
class MEM {
private:
ubyte[] memory;//varsayılan değerin 0xFF değil 0x00 olması gerektiğini fark ettim :)
size_t freeLocated, memSize;
public:
immutable byteSize = 8; // bits...
this(size_t minSize) {
size_t isOverload = minSize % byteSize;
memory = new ubyte[](minSize - isOverload);
memSize = memory.length;
}
private void extendMem() {
memory.length += memSize * 2;
memSize = memory.length;
}
final void memLoadBytes(inout ubyte[] data) @property {
auto mem = cast(ubyte*) malloc(data.length);
mem[0..data.length] = data;
}
final void* malloc(size_t size) {
if(memSize < freeLocated + size) {
extendMem();
}
scope(exit) freeLocated += size;
return &memory[freeLocated];
}
final void memWrite(inout(string) data) @property {//inout çünkü char[] de gelebilsin.
auto mem = cast(char*) malloc(data.length);
mem[0..data.length] = data;//Bunun daha hızlı olabileceğini düşündüm ama emin değilim.
/* foreach(i, chr; data) {
*(cast(char*)mem + i) = chr;
}*/
}
final uint memReserveAddress() {
/*
Burada adres döndürmeyi çok isterdim ama memory.ptr sürekli olarak değişiyor.
Bende dizi üzerindeki adresini döndürmeyi tercih ettim.
*/
scope(exit) malloc(int.sizeof);
return freeLocated;
}
final void memSetAddress(uint adrl) {
*cast(uint*) &memory[adrl] = memory.length;
}
void memLoadString(inout(string) data) @property {
auto mem = cast(char*) malloc(data.length + ubyte.sizeof);
*(cast(ubyte*)mem) = cast(ubyte) data.length;
mem[ubyte.sizeof..data.length+ubyte.sizeof] = data;
}
override string toString() const{
import std.range : repeat;
string memImage = " DECIMAL MEMORY DUMP ASCII \n";
memImage ~= format("%s\n", repeat('-', memImage.length)) ;
for(int i; i < memory.length; i += byteSize) {
auto row = memory[i..i + byteSize].dup;
/*
Çıktının doğru verilmesi için \0 görülen yeri 0xFF olarak değiştirdim.
Bunun asıl veriyi etkilemesi ise sağlıksız olacaktır o yüzden dup kullandım.
nasıl olsa toString sadece debug işlemimiz için olacak
o halde dup edip hız kaybımız olması bizim için sorun olmaz
*/
foreach(ref ubyte address; row) {
if(address == 0){
address = 0xFF;
memImage ~= " ";
}else if(address < 10) memImage ~= " ";
else if(address < 100) memImage ~= " ";
else if(address < 256) memImage ~= " ";
memImage ~= to!string(address);
}
memImage ~= " ";
foreach(c; row){
memImage ~= c;
}
memImage ~= "\n";
}
writeln(format("%s>Total %s bytes<\n", repeat(' ', 10), memory.length));
return memImage ~ format("%s>Total %s bytes<\n", repeat(' ', 10), memory.length);
}
}
Zekeriya
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]