diff dmd/backend/glue.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 2cc604139636
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/backend/glue.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,552 @@
+module dmd.backend.glue;
+
+import dmd.Array;
+import dmd.Dsymbol;
+import dmd.File;
+import dmd.FileName;
+import dmd.Library;
+import dmd.OutBuffer;
+import dmd.Module;
+import dmd.Identifier;
+import dmd.AssertExp;
+import dmd.TOK;
+import dmd.Global;
+import dmd.Param;
+import dmd.backend.Config;
+import dmd.backend.Configv;
+import dmd.backend.StringTab;
+
+import core.stdc.string;
+
+__gshared Array obj_symbols_towrite;
+
+extern (C++) extern
+{
+	__gshared Outbuffer objbuf;
+	int go_flag(char* cp);
+	void util_set64();
+	void util_set386();
+}
+
+import std.contracts;
+import std.string;
+
+string lastmname;
+
+struct Outbuffer
+{
+    ubyte* buf;		// the buffer itself
+    ubyte* pend;	// pointer past the end of the buffer
+    ubyte* p;		// current position in buffer
+    uint len;		// size of buffer
+    uint inc;		// default increment size
+
+    this(uint inc)
+	{
+		assert(false);
+	}
+	
+    ~this()
+	{
+		assert(false);
+	}
+	
+    void reset()
+	{
+		assert(false);
+	}
+
+    // Reserve nbytes in buffer
+    void reserve(uint nbytes)
+	{
+		assert(false);
+	}
+
+    // Write n zeros; return pointer to start of zeros
+    void* writezeros(uint n)
+	{
+		assert(false);
+	}
+
+    // Position buffer to accept the specified number of bytes at offset
+    int position(uint offset, uint nbytes);
+
+    // Write an array to the buffer, no reserve check
+    void writen(const(void)* b, int len)
+    {
+		memcpy(p,b,len);
+		p += len;
+    }
+
+    // Clear bytes, no reserve check
+    void clearn(int len)
+    {
+		int i;
+		for (i=0; i< len; i++)
+			*p++ = 0;
+    }
+
+    // Write an array to the buffer.
+    void write(const void *b, int len)
+	{
+		assert(false);
+	}
+
+    void write(Outbuffer* b)
+	{
+		write(b.buf, b.p - b.buf);
+	}
+
+    /**
+     * Flushes the stream. This will write any buffered
+     * output bytes.
+     */
+    void flush() { }
+
+    /**
+     * Writes an 8 bit byte, no reserve check.
+     */
+    void writeByten(char v)
+    {
+		*p++ = v;
+    }
+
+    /**
+     * Writes an 8 bit byte.
+     */
+    void writeByte(int v)
+	{
+		assert(false);
+	}
+
+    /**
+     * Writes a 16 bit little-end short, no reserve check.
+     */
+    void writeWordn(int v)
+    {
+version (_WIN32) {
+		*cast(ushort*)p = cast(short)v;
+} else {
+		p[0] = v;
+		p[1] = v >> 8;
+}
+		p += 2;
+    }
+
+    /**
+     * Writes a 16 bit little-end short.
+     */
+    void writeWord(int v)
+    {
+		reserve(2);
+		writeWordn(v);
+    }
+
+    /**
+     * Writes a 16 bit big-end short.
+     */
+    void writeShort(int v)
+    {
+		if (pend - p < 2)
+			reserve(2);
+
+static if (false) {
+		p[0] = (cast(ubyte*)&v)[1];
+		p[1] = v;
+} else {
+		ubyte* q = p;
+		q[0] = cast(ubyte)(v >> 8);
+		q[1] = cast(ubyte)v;
+}
+		p += 2;
+    }
+
+    /**
+     * Writes a 16 bit char.
+     */
+    void writeChar(int v)
+    {
+		writeShort(v);
+    }
+
+    /**
+     * Writes a 32 bit int.
+     */
+    void write32(long v)
+	{
+		assert(false);
+	}
+
+    /**
+     * Writes a 64 bit long.
+     */
+///#if __INTSIZE == 4
+    void write64(long v)
+	{
+		assert(false);
+	}
+///#endif
+
+    /**
+     * Writes a 32 bit float.
+     */
+    void writeFloat(float v)
+	{
+		assert(false);
+	}
+
+    /**
+     * Writes a 64 bit double.
+     */
+    void writeDouble(double v)
+	{
+		assert(false);
+	}
+
+    void write(const(char)* s)
+	{
+		assert(false);
+	}
+
+    void write(const(ubyte)* s)
+	{
+		assert(false);
+	}
+
+    void writeString(const(char)* s)
+	{
+		assert(false);
+	}
+
+    void prependBytes(const(char)* s)
+	{
+		assert(false);
+	}
+
+    void bracket(char c1, char c2)
+	{
+		assert(false);
+	}
+
+    /**
+     * Returns the number of bytes written.
+     */
+    int size()
+    {
+		return p - buf;
+    }
+
+    char* toString()
+	{
+		assert(false);
+	}
+	
+    void setsize(uint size)
+	{
+		assert(false);
+	}
+
+    void writesLEB128(long value)
+	{
+		assert(false);
+	}
+	
+    void writeuLEB128(uint value)
+	{
+		assert(false);
+	}
+}
+
+static this()
+{
+	obj_symbols_towrite = new Array();
+}
+
+/**************************************
+ * Append s to list of object files to generate later.
+ */
+ 
+void obj_append(Dsymbol s)
+{
+    obj_symbols_towrite.push(cast(void*)s);
+}
+
+extern (C++) {
+	void backend_init();
+	void backend_term();
+	void obj_term();
+	void rtlsym_reset();
+    void slist_reset();
+	void el_reset();
+	void cg87_reset();
+	void out_reset();
+	void obj_init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname);
+}
+
+void clearStringTab()
+{
+    //printf("clearStringTab()\n");
+    memset(stringTab.ptr, 0, stringTab.sizeof);
+    stidx = 0;
+
+    assertexp_sfilename = null;
+    assertexp_name = null;
+    assertexp_mn = null;
+}
+
+void obj_start(char *srcfile)
+{
+    //printf("obj_start()\n");
+
+    out_config_init();
+
+    rtlsym_reset();
+    slist_reset();
+    clearStringTab();
+
+    obj_init(&objbuf, srcfile, null);
+
+    el_reset();
+    cg87_reset();
+    out_reset();
+}
+
+void obj_end(Library library, File objfile)
+{
+	obj_term();
+
+    if (library)
+    {
+		// Transfer image to library
+		library.addObject(objfile.name.toChars(), objbuf.buf, objbuf.p - objbuf.buf);
+		objbuf.buf = null;
+    }
+    else
+    {
+		// Transfer image to file
+		objfile.setbuffer(objbuf.buf, objbuf.p - objbuf.buf);
+		objbuf.buf = null;
+
+		string p = FileName.path(objfile.name.toChars());
+		FileName.ensurePathExists(p);
+		//mem.free(p);
+
+		//printf("write obj %s\n", objfile.name.toChars());
+		objfile.writev();
+    }
+
+    objbuf.pend = null;
+    objbuf.p = null;
+    objbuf.len = 0;
+    objbuf.inc = 0;
+}
+
+void obj_write_deferred(Library library)
+{
+	for (int i = 0; i < obj_symbols_towrite.dim; i++)
+    {	
+		Dsymbol s = cast(Dsymbol)obj_symbols_towrite.data[i];
+		Module m = s.getModule();
+
+		string mname;
+		if (m)
+		{   
+			mname = m.srcfile.toChars();
+			lastmname = mname;
+		}
+		else
+		{
+			//mname = s->ident->toChars();
+			mname = lastmname;
+			assert(mname.length != 0);
+		}
+
+		obj_start(cast(char*)toStringz(mname));
+
+		static int count;
+		count++;		// sequence for generating names
+
+		/* Create a module that's a doppelganger of m, with just
+		 * enough to be able to create the moduleinfo.
+		 */
+		OutBuffer idbuf = new OutBuffer();
+		idbuf.printf("%s.%d", m ? m.ident.toChars() : mname, count);
+		string idstr = idbuf.extractString();
+		idbuf.data = null;
+		Identifier id = new Identifier(idstr, TOK.TOKidentifier);
+
+		Module md = new Module(mname, id, 0, 0);
+		md.members = new Array();
+		md.members.push(cast(void*)s);	// its only 'member' is s
+		if (m)
+		{
+			md.doppelganger = 1;	// identify this module as doppelganger
+			md.md = m.md;
+			md.aimports.push(cast(void*)m);	// it only 'imports' m
+			md.massert = m.massert;
+			md.marray = m.marray;
+		}
+
+		md.genobjfile(0);
+
+		/* Set object file name to be source name with sequence number,
+		 * as mangled symbol names get way too long.
+		 */
+		string fname = FileName.removeExt(mname);
+		
+		OutBuffer namebuf = new OutBuffer();
+		uint hash = 0;
+		foreach (char c; s.toChars())
+			hash += c;
+
+		namebuf.printf("%s_%x_%x.%s", fname, count, hash, global.obj_ext);
+		fname = namebuf.extractString();
+
+		//printf("writing '%s'\n", fname);
+		File objfile = new File(fname);
+		obj_end(library, objfile);
+    }
+
+    obj_symbols_towrite.dim = 0;
+}
+
+/**************************************
+ * Initialize config variables.
+ */
+
+void out_config_init()
+{
+    Param* params = &global.params;
+
+    if (!config.target_cpu)
+    {
+		config.target_cpu = TARGET_PentiumPro;
+		config.target_scheduler = config.target_cpu;
+    }
+    config.fulltypes = CVNONE;
+    config.inline8087 = 1;
+    config.memmodel = 0;
+    config.flags |= CFGuchar;	// make sure TYchar is unsigned
+version (TARGET_WINDOS) {
+    if (params.isX86_64)
+		config.exe = EX_WIN64;
+    else
+		config.exe = EX_NT;
+
+    // Win32 eh
+    config.flags2 |= CFG2seh;
+
+    if (params.run)
+		config.wflags |= WFexe;		// EXE file only optimizations
+    else if (params.link && !global.params.deffile)
+		config.wflags |= WFexe;		// EXE file only optimizations
+    else if (params.exefile)		// if writing out EXE file
+    {	
+		size_t len = params.exefile.length;
+		if (len >= 4 && icmp(params.exefile[len-3..len], "exe") == 0)
+			config.wflags |= WFexe;
+    }
+    config.flags4 |= CFG4underscore;
+}
+version (TARGET_LINUX) {
+    if (params.isX86_64)
+		config.exe = EX_LINUX64;
+    else
+		config.exe = EX_LINUX;
+    config.flags |= CFGnoebp;
+    config.flags |= CFGalwaysframe;
+    if (params.pic)
+		config.flags3 |= CFG3pic;
+}
+version (TARGET_OSX) {
+    if (params.isX86_64)
+		config.exe = EX_OSX64;
+    else
+		config.exe = EX_OSX;
+    config.flags |= CFGnoebp;
+    config.flags |= CFGalwaysframe;
+    if (params.pic)
+		config.flags3 |= CFG3pic;
+}
+version (TARGET_FREEBSD) {
+    if (params.isX86_64)
+		config.exe = EX_FREEBSD64;
+    else
+		config.exe = EX_FREEBSD;
+    config.flags |= CFGnoebp;
+    config.flags |= CFGalwaysframe;
+    if (params.pic)
+		config.flags3 |= CFG3pic;
+}
+version (TARGET_SOLARIS) {
+    if (params.isX86_64)
+		config.exe = EX_SOLARIS64;
+    else
+		config.exe = EX_SOLARIS;
+    config.flags |= CFGnoebp;
+    config.flags |= CFGalwaysframe;
+    if (params.pic)
+		config.flags3 |= CFG3pic;
+}
+    config.flags2 |= CFG2nodeflib;	// no default library
+    config.flags3 |= CFG3eseqds;
+static if (false) {
+    if (env.getEEcontext().EEcompile != 2)
+		config.flags4 |= CFG4allcomdat;
+    if (env.nochecks())
+		config.flags4 |= CFG4nochecks;	// no runtime checking
+} else version (TARGET_OSX) {
+} else {
+    config.flags4 |= CFG4allcomdat;
+}
+    if (params.trace)
+		config.flags |= CFGtrace;	// turn on profiler
+    if (params.nofloat)
+		config.flags3 |= CFG3wkfloat;
+
+    configv.verbose = params.verbose;
+
+    if (params.optimize)
+		go_flag(cast(char*)"-o".ptr);
+
+    if (params.symdebug)
+    {
+version (ELFOBJ_OR_MACHOBJ) {
+	configv.addlinenumbers = 1;
+	config.fulltypes = (params.symdebug == 1) ? CVDWARF_D : CVDWARF_C;
+}
+version (OMFOBJ) {
+	configv.addlinenumbers = 1;
+	config.fulltypes = CV4;
+}
+	if (!params.optimize)
+	    config.flags |= CFGalwaysframe;
+    }
+    else
+    {
+		configv.addlinenumbers = 0;
+		config.fulltypes = CVNONE;
+		//config.flags &= ~CFGalwaysframe;
+    }
+
+    if (params.isX86_64)
+    {
+		util_set64();
+		cod3_set64();
+    }
+    else
+    {
+		util_set386();
+		cod3_set386();
+    }
+
+debug {
+    debugb = params.debugb;
+    debugc = params.debugc;
+    debugf = params.debugf;
+    debugr = params.debugr;
+    debugw = params.debugw;
+    debugx = params.debugx;
+    debugy = params.debugy;
+}
+}
\ No newline at end of file