fis-gtm/sr_port/compiler_startup.c

196 lines
5.9 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "compiler.h"
#include "opcode.h"
#include "cmd_qlf.h"
#include "mdq.h"
#include "cgp.h"
#include "error.h"
#include "mmemory.h"
#include "stringpool.h"
#include "list_file.h"
#include "source_file.h"
#include "lb_init.h"
#include "reinit_externs.h"
#include "comp_esc.h"
#include "resolve_blocks.h"
#include "hashtab_str.h"
#define HOPELESS_COMPILE 128
GBLREF short int source_column, source_line;
/* ensure source_buffer is aligned on a int4 word boundary so that
* we can calculate the checksum a longword at a time.
*/
GBLREF int4 aligned_source_buffer[MAX_SRCLINE / SIZEOF(int4) + 1];
GBLREF unsigned char *source_buffer;
GBLREF src_line_struct src_head;
GBLREF triple t_orig, *curr_fetch_trip, *curr_fetch_opr;
GBLREF int4 curr_fetch_count;
GBLREF command_qualifier cmd_qlf;
GBLREF int mlmax;
GBLREF mline mline_root;
GBLREF char cg_phase; /* code generation phase */
GBLREF boolean_t mstr_native_align, save_mstr_native_align;
GBLREF hash_table_str *complits_hashtab;
LITDEF char compile_terminated[] = "COMPILATION TERMINATED DUE TO EXCESS ERRORS";
boolean_t compiler_startup(void)
{
#ifdef DEBUG
void dumpall();
#endif
boolean_t compile_w_err;
unsigned char err_buf[45];
unsigned char *cp, *cp2;
int errknt;
int4 n;
uint4 checksum, line_count;
mlabel *null_lab;
src_line_struct *sl;
mident null_mident;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
assert(NULL == complits_hashtab || NULL == complits_hashtab->base);
memset(&null_mident, 0, SIZEOF(null_mident));
ESTABLISH_RET(compiler_ch, FALSE);
/* Since the stringpool alignment is solely based on mstr_native_align, we need to initialize it based
* on the ALIGN_STRINGS qualifier so that all strings in the literal text pool are aligned.
* However, when a module is compiled at runtime, we need to preserve the existing runtime setting
* (that was initialized at GT.M startup) once the compilation is done. save_mstr_native_align is used for
* this purpose. */
save_mstr_native_align = mstr_native_align;
/* mstr_native_align = (cmd_qlf.qlf & CQ_ALIGN_STRINGS) ? TRUE : FALSE; */
mstr_native_align = FALSE; /* TODO: remove this line and uncomment the above line */
cg_phase = CGP_NOSTATE;
TREF(source_error_found) = errknt = 0;
if(!open_source_file())
{
mstr_native_align = save_mstr_native_align;
REVERT;
return FALSE;
}
cg_phase = CGP_PARSE;
if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
{
if (cmd_qlf.qlf & CQ_MACHINE_CODE)
dqinit(&src_head, que);
open_list_file();
}
if (cmd_qlf.qlf & CQ_CE_PREPROCESS)
open_ceprep_file();
tripinit();
null_lab = get_mladdr(&null_mident);
null_lab->ml = &mline_root;
mlmax++;
curr_fetch_trip = curr_fetch_opr = newtriple(OC_LINEFETCH);
curr_fetch_count = 0;
TREF(code_generated) = FALSE;
checksum = 0;
line_count = 1;
for (source_line = 1; errknt <= HOPELESS_COMPILE; source_line++)
{
if (-1 == (n = read_source_file()))
break;
if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
{
if (cmd_qlf.qlf & CQ_MACHINE_CODE)
{
sl = (src_line_struct *)mcalloc(SIZEOF(src_line_struct));
dqins(&src_head, que, sl);
sl->addr = mcalloc(n + 1); /* +1 for zero termination */
sl->line = source_line;
memcpy(sl->addr, source_buffer, n + 1);
} else
{
list_line_number();
list_line((char *)source_buffer);
}
}
/* calculate checksum */
RTN_SRC_CHKSUM((char *)source_buffer, n, checksum);
TREF(source_error_found) = 0;
lb_init();
if (cmd_qlf.qlf & CQ_CE_PREPROCESS)
put_ceprep_line();
if (!line(&line_count))
{
assert(TREF(source_error_found));
errknt++;
}
}
close_source_file();
if (cmd_qlf.qlf & CQ_CE_PREPROCESS)
close_ceprep_file();
cg_phase = CGP_RESOLVE;
if (t_orig.exorder.fl == &t_orig) /* if no lines in routine, set up line 0 */
newtriple(OC_LINESTART);
newtriple(OC_RET); /* always provide a default QUIT */
mline_root.externalentry = t_orig.exorder.fl;
INVOKE_STP_GCOL(0);
/* The above invocation of stp_gcol with a parameter of 0 is a critical part of compilation
* (both routine compilations and indirect dynamic compilations). This collapses the indirect
* (compilation) stringpool so that only the literals are left. This stringpool is then written
* out to the compiled object as the literal pool for that compilation. Temporary stringpool
* use for conversions or whatever are eliminated. Note the path is different in stp_gcol for
* the indirect stringpool which is only used during compilations.
*/
start_fetches(OC_NOOP);
resolve_blocks();
errknt = resolve_ref(errknt);
compile_w_err = (errknt <= HOPELESS_COMPILE && (cmd_qlf.qlf & CQ_IGNORE));
if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
{
list_line("");
if (errknt)
cp = i2asc(err_buf, errknt);
else
{
cp = err_buf;
*cp++ = 'n';
*cp++ = 'o';
}
memcpy(cp, " error", SIZEOF(" error"));
cp += SIZEOF(" error") - 1;
if (1 != errknt)
*cp++ = 's';
*cp = 0;
list_line((char *)err_buf);
if (errknt > HOPELESS_COMPILE)
list_line((char *)compile_terminated);
if (cmd_qlf.qlf & CQ_MACHINE_CODE && compile_w_err)
list_head(1);
}
if ((!errknt || compile_w_err) && (cmd_qlf.qlf & CQ_OBJECT || cmd_qlf.qlf & CQ_MACHINE_CODE))
{
obj_code(line_count, checksum);
cg_phase = CGP_FINI;
}
if (cmd_qlf.qlf & CQ_LIST || cmd_qlf.qlf & CQ_CROSS_REFERENCE)
{
list_cmd();
close_list_file();
}
COMPILE_HASHTAB_CLEANUP;
reinit_externs();
mstr_native_align = save_mstr_native_align;
REVERT;
return errknt ? TRUE : FALSE;
}