blob: 9e78b4feceba04719a8b40587e5bfe992e57ce07 [file] [log] [blame]
/* --COPYRIGHT--,EPL
* Copyright (c) 2008 Texas Instruments and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Texas Instruments - initial implementation
*
* --/COPYRIGHT--*/
package xdc.services.intern.gen;
import org.mozilla.javascript.*;
import xdc.services.global.*;
import xdc.services.spec.*;
import xdc.services.intern.xsr.*;
import xdc.services.intern.cmd.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class Config
{
private static final int MOD = 0;
private static final int INST = 1;
private static final int STRUCT = 2;
private static final int DCLMODE = 0;
private static final int VALMODE = 1;
private static final int STATIC_POLICY = 0;
private static final int DELETE_POLICY = 2;
private static final int IOBJ_BASIC = 0;
private static final int IOBJ_PROXY = 1;
private static final int IOBJ_DLGST = 2;
private static final int IOBJ_DLGPR = 3;
private static final int L_ENTRY = 0x1;
private static final int L_EXIT = 0x2;
private static final int L_LIFECYCLE = 0x4;
private enum FxnKind { ROM_E, ROM_R, RAM_E };
private static boolean isasm;
private static boolean isrom;
private static int mode;
private HashSet<Value.Obj> asmset = new HashSet();
private HashSet<String> baseset = new HashSet();
private ArrayList<String> clvec = new ArrayList();
private ArrayList<Value.Obj> modvec = new ArrayList();
private HashMap<String,Value.Obj> modmap = new HashMap<String,Value.Obj>();
private HashSet<Value.Obj> modset = new HashSet();
private HashSet<String> pkgset = new HashSet();
private HashSet<String> romset = new HashSet();
private HashSet<String> strset = new HashSet();
private int mInitCnt = 0;
private Glob glob;
private Prog progGen;
Config( Glob glob, Prog progGen )
{
this.glob = glob;
this.progGen = progGen;
}
/*
* ======== gen ========
*/
void gen(Value om, Value prog, Out out)
throws JavaScriptException
{
glob.mode = Glob.CDLMODE;
glob.out = out;
isasm = prog.geti("$$isasm") > 0;
isrom = prog.geti("$$isrom") > 0;
genPrologue();
/* loop over all modules in the configuration */
Value modarr = om.getv("$modules");
for (int i = 0; i < modarr.geti("length"); i++) {
Value.Obj m = ((Value.Obj)(modarr.getv(i))).getOrig();
/* skip over modules that are not used */
if (m.geti("$used") == 0) {
continue;
}
if (m.geti("$hostonly") == 1) {
continue;
}
/* Code.asmset contains all mods that need runtime and
* are in packages that have not been excluded from gen
*/
if (!unitSpec(m).needsRuntime()) {
continue;
}
if (m.getv("$package").geti("$$genflg") == 1) {
asmset.add(m.getOrig());
}
if (!isasm(m)) {
continue;
}
/* modvec contains all used modules */
modvec.add(m);
modmap.put(m.gets("$name"), m);
if (m.has("MODULE_STARTUP$", m) && m.geti("MODULE_STARTUP$") == 1){
mInitCnt++;
}
pkgset.add(m.getv("$package").gets("$$qn"));
}
Collections.sort(modvec);
/* includes */
glob.genTitle("MODULE INCLUDES");
for (Value.Obj m : modvec) {
genInclude(m);
}
skip();
/* internals */
for (Value.Obj m : modvec) {
genInternals(m);
}
/* inherits */
/* We call genModInherits twice, once to find modules imported from
* ROM and populate romset, and the second time to actually generate
* constants.
*/
for (Value.Obj m : modvec) {
genModInherits(m, true);
}
for (Value.Obj m : modvec) {
genModInherits(m, false);
}
/* vtable */
for (Value.Obj m : modvec) {
genFxnTabV(m);
}
/* mtable */
for (Value.Obj m : modvec) {
genFxnTabM(m);
}
mode = DCLMODE;
/* declarations */
for (Value.Obj m : modvec) {
genTitle(m, "DECLARATIONS");
genMod(m);
}
/* embedded object offsets */
for (Value.Obj m : modvec) {
genOffsets(m);
}
/* templates */
for (int i = 0; i < modarr.geti("length"); i++) {
Value.Obj m = ((Value.Obj)(modarr.getv(i))).getOrig();
if (m.geti("$used") != 0) {
genTemplate(m);
}
}
mode = VALMODE;
strset = new HashSet();
/* initializers */
for (Value.Obj m : modvec) {
genTitle(m, "INITIALIZERS");
genMod(m);
}
/* function stubs */
for (Value.Obj m : modvec) {
if (isrom) {
genFxnStubs(m, FxnKind.ROM_E);
genFxnStubs(m, FxnKind.ROM_R);
}
else {
genFxnStubs(m, FxnKind.RAM_E);
}
}
/* proxy bodies */
for (Value.Obj m : modvec) {
genProxy(m, isrom);
}
/* create support */
for (Value.Obj m : modvec) {
genCreate(m);
}
/* system functions */
for (Value.Obj m : modvec) {
genSysFxns(m);
}
/* pragmas */
for (Value.Obj m : modvec) {
genPragmas(m);
}
if (!isrom) {
genPostInit();
}
glob.genTitle("PROGRAM GLOBALS");
genGlobals(prog, false);
/* clink */
glob.genTitle("CLINK DIRECTIVES");
for (String ns : clvec) {
glob.genClink(ns);
}
/*
glob.out.print("#ifdef __ti__\n");
glob.genClinkMacro();
for (String ns : clvec) {
glob.out.printf("xdc__clink_constant(%1);\n", ns);
}
glob.out.printf("#endif\n\n");
*/
Value pkgarr = om.getv("$packages");
Hashtable<String,String> aliases = new Hashtable<String,String>();
for (int i = 0; i < pkgarr.geti("length"); i++) {
Value.Obj pkg = ((Value.Obj)(pkgarr.getv(i))).getOrig();
getPkgAliases(pkg, modmap, aliases);
}
prog.bind("$$aliases", aliases);
}
/*
* ======== genAgg ========
*/
private void genAgg(Value.Obj agg)
{
if (agg.geti("$hostonly") == 1) {
return;
}
String ts = agg.getProto().tname();
int ot = otype(ts);
if (ot != STRUCT) {
return; /// FOR NOW!!!!!
}
Value.Obj obj = (Value.Obj)agg.getv("$object");
if (obj == null && ts.endsWith(".Object")) {
xdc.services.intern.xsr.Err.exit("can't initialize private statically (" + ts + ')');
return;
}
glob.out.printf("{\n%+");
if (obj != null) {
Value.Obj mod = (Value.Obj)agg.getv("$module");
genInstObj(obj, mod, glob.mkCname(mod.gets("$name")));
glob.out.printf("%-%t");
return;
}
if (ts.endsWith(".Params")) {
String cs = ts.replace('.', '_');
glob.out.printf("%tsizeof (%1), /* __size */\n", cs);
}
genFlds(agg);
glob.out.printf("%-%t");
}
/*
* ======== genArr ========
*/
private void genArr(Value.Arr arr, String aname, Value.Obj obj,
String path, boolean isConst)
{
if (obj.geti("$hostonly") == 1 || aname.startsWith("$")) {
return;
}
String ts = obj.getProto().tname();
int k = ts.lastIndexOf('.');
String pre = ts.substring(0, k);
genArr(arr, glob.mkCname(pre), aname, "", path, isConst);
}
private void genArr(Value.Arr arr, String cname, String an, String xs,
String path, boolean isConst )
{
Proto.Arr parr = arr.getProto();
Proto base = parr.getBase();
int len = arr.geti("length");
if (base instanceof Proto.Pred && !arr.isVirgin()) {
for (int i = 0; i < len; i++) {
Object oval = arr.get(i, arr);
String ps = path + '[' + String.valueOf(i) + ']';
if (base instanceof Proto.Str) {
genPreds((Value.Obj)oval, ps, xs + '_' + i, isConst);
}
else if (oval instanceof Value.Arr) {
genArr((Value.Arr)oval, cname, an, xs + '_' + i, ps, isConst);
}
else if (oval instanceof Extern) {
genExt((Extern)oval);
}
else if (oval instanceof Value.Obj) {
genStruct((Value.Obj)oval, isConst);
}
}
}
if (len == 0 || parr.getDim() > 0) {
return;
}
arr.setCtype("__T" + parr.depth() + "_" + cname + an);
if (mode == VALMODE && isConst && !arr.isVirgin() && arr.getMemSect() == null) {
clink(aname(arr));
}
glob.genTitleD("--> " + aname(arr));
glob.out.printf("%4%1 %2[%3]",
arr.getCtype(),
aname(arr),
Integer.toString(len),
isConst ? "const " : "");
if (mode == VALMODE) {
genArrVals(arr, an, xs, true);
}
glob.out.printf(";\n");
if (mode == DCLMODE && arr.getMemSect() != null) {
glob.out.printf("#ifdef __ti__sect\n");
glob.out.printf("%+%t#pragma DATA_SECTION(%1, \"%2\");\n%-", aname(arr), arr.getMemSect());
glob.out.printf("#endif\n");
glob.out.printf("#ifdef __GNUC__\n#if __GNUC__ >= 4\n");
glob.out.printf("%4%1 %2[%3]", arr.getCtype(), aname(arr),
Integer.toString(len), isConst ? "const " : "");
glob.out.printf(" __attribute__ ((section(\"%1\")));\n",
arr.getMemSect());
glob.out.printf("%4%1 %2[%3]", arr.getCtype(), aname(arr),
Integer.toString(len), isConst ? "const " : "");
glob.out.printf(" __attribute__ ((externally_visible));\n",
arr.getMemSect());
glob.out.printf("#endif\n#endif\n");
}
if (mode == DCLMODE && arr.getMemAlign() != 0) {
glob.out.printf("#ifdef __ti__align\n");
glob.out.printf("%+%t#pragma DATA_ALIGN(%1, %2);\n%-", aname(arr), Integer.toString(arr.getMemAlign()));
glob.out.printf("#endif\n");
}
}
/*
* ======== genArrVals ========
*/
private void genArrVals(Value.Arr arr, String an, String xs)
{
genArrVals(arr, an, xs, false);
}
private void genArrVals(Value.Arr arr, String an, String xs, boolean top)
{
if (arr.isVirgin()) {
return;
}
int len = arr.geti("length");
glob.out.printf("%1{\n%+", top ? " = " : "");
for (int i = 0; i < len; i++) {
Object oval = arr.get(i, arr);
if (undef(oval)) {
arr.error("element [" + i + "] is undefined");
continue;
}
glob.out.printf("%t");
genVal(arr.getProto().getBase(), oval);
glob.out.printf(", /* %1 */\n", "[" + i + "]");
}
glob.out.printf("%-%1", top ? "}" : "");
}
/*
* ======== genCreate ========
*/
void genCreate( Value.Obj mod )
{
Unit unit = unitSpec(mod);
if (!unit.isInst() || unit.isProxy()) {
return;
}
boolean hasHeap = commonGetv(mod, "instanceHeap") != null;
if (isrom && hasHeap) {
return;
}
if (mod.geti("$$scope") == -1 && !hasHeap) {
return;
}
genTitle(mod, "OBJECT DESCRIPTOR");
Value.Obj vref = (Value.Obj)commonGetv(mod, "instanceHeap");
String instHeap = vref != null ? valToStr(vref) : null;
Unit dlg = unit.delegatesTo();
if (dlg != null && dlg.isInst() && !unit.isSized()) {
String icn = glob.mkCname(dlg.getQualName());
glob.out.printf("extern %1Handle %2Object_delegate( %2Object* obj )", icn, glob.cname);
glob.out.printf(" { return ((%1Handle)&((%2Object__*)obj)->__deleg); }\n", icn, glob.cname);
}
String ns = glob.cname + "Object__DESC__C";
String cs = "xdc_runtime_Core_";
glob.genTitleD("Object__DESC__C");
glob.out.printf("%ttypedef struct { %1Object2__ s0; char c; } %1__S1;\n", glob.cname);
glob.out.printf("__FAR__ const %1ObjDesc %2 = {\n%+", cs, ns);
if (unit.isHeir()) {
if (commonGeti(mod, "fxntab") == 1) {
glob.out.printf("%t(Ptr)&%1Module__FXNS__C, /* fxnTab */\n", glob.cname);
}
else {
glob.out.printf("%t(Ptr)0, /* fxnTab */\n");
}
}
else {
glob.out.printf("%t(Ptr)-1, /* fxnTab */\n");
}
if (commonGeti(mod, "memoryPolicy") != STATIC_POLICY) {
glob.out.printf("%t&%1Module__root__V.link, /* modLink */\n", glob.cname);
}
else {
glob.out.printf("%t(Ptr)0, /* modLink */\n");
}
glob.out.printf("%tsizeof(%1__S1) - sizeof(%1Object2__), /* objAlign */\n", glob.cname);
glob.out.printf("%t%1, /* objHeap */\n", instHeap != null ? instHeap : "0");
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%toffsetof(%1Object__, __name), /* objName */\n", glob.cname);
}
else {
glob.out.printf("%t0, /* objName */\n");
}
glob.out.printf("%tsizeof(%1Object2__), /* objSize */\n", glob.cname);
glob.out.printf("%t(Ptr)&%1Object__PARAMS__C, /* prmsInit */\n", glob.cname);
glob.out.printf("%tsizeof(%1Params), /* prmsSize */\n", glob.cname);
glob.out.printf("%-};\n");
skip();
}
/*
* ======== genCreateSig ========
*/
private void genCreateSig()
{
glob.out.printf("%2Ptr %1Object__create__S (%+\n%t%2Ptr oa,\n%t%2SizeT osz,", glob.cname, "xdc_");
glob.out.printf("\n%tconst xdc_Ptr aa,\n%tconst %1__ParamsPtr pa,\n%txdc_SizeT psz,\n%t%2 eb%- )\n{\n%+",
glob.cname, Glob.ERRBLK);
}
/*
* ======== genError ========
*/
private void genError( Unit unit, String kind )
{
String msgC = "xdc_runtime_Core_S_" + kind + "_POLICY_ERROR__C";
glob.out.printf("%t%1_raiseX(NULL, %2Module__id__C, NULL, 0, %1_E_generic, (xdc_IArg)%3, 0);\n",
"xdc_runtime_Error", glob.cname, msgC);
}
/*
* ======== genExt ========
*/
private void genExt(Extern ext)
{
if (mode == DCLMODE && ext.isRaw()
&& ext.getName().matches("\\s*[a-zA-Z_]\\w*")) {
glob.genTitleD("--> " + ext.getName());
if (ext.isFxnT()) {
if (ext.getSig() == null) {
glob.out.printf("extern void %1();\n", ext.getName());
}
else {
glob.out.printf("extern %1;\n",
ext.getSig().replace("(*)", " " + ext.getName()));
}
}
else {
if (ext.getSig() == null) {
glob.out.printf("extern void* %1;\n", ext.getName());
}
else {
glob.out.printf("extern %1 %2;\n", ext.getSig(), ext.getName());
}
}
}
}
/*
* ======== genFixup ========
*/
private void genFixup(Value.Obj mod, Unit u)
{
String cname = glob.mkCname(u.getQualName());
glob.genTitleD("__ParamsPtr");
glob.out.printf("#ifdef %1__VERS\n", cname);
glob.out.printf("%+%t#define %1__ParamsPtr xdc_UChar*\n%-", cname);
glob.out.printf("#else\n");
glob.out.printf("%+%t#define %1__ParamsPtr xdc_Ptr\n%-", cname);
glob.out.printf("#endif\n");
}
/*
* ======== genFlds ========
*/
private void genFlds(Value.Obj vobj)
{
for (Member fld : vobj.getProto().allFlds()) {
if (fld.isMeta() || fld.getName().startsWith("$")) {
continue;
}
Object fldval = vobj.get(fld.getName(), vobj);
if (undef(fldval)) {
vobj.error("'" + fld.getName() + "' is undefined");
continue;
}
glob.out.printf("%t");
genVal(fld.getProto(), fldval);
glob.out.printf(", /* %1 */\n", fld.getName());
}
}
/*
* ======== genFxnBody ========
* Generate a __E (or __R) function that delagates to the "real"
* function.
*
* In the non-ROM case:
* __E calls either __F or __PATCH based on a #define of __PATCH
*
* __PATCH is defined in Code.java when a module's $$patchsyms names
* the function to be patched.
*
* In the ROM case:
* ???
*
* var-arg functions are generated twice:
* first we generate a fixed arg stub that takes a va_list arg
* the second uses "..." and simply calls the first
*
* caller *.c callee
* ---------------------- ----------------- ---------
* foo(...) := foo__E(...) foo__E(...)
* |
* +->foo_va__F(va) foo_va(va) := foo_va__F(va)
*
* ???? foo_va__E(va)
* |
* +->foo_va__F(va)
*
* The vargs parameter is set to false for the first pass and true for
* the second pass but only for vararg functions.
*/
private void genFxnBody(Unit unit, Decl.Fxn fxn, FxnKind kind, int mask, int ptab, String patch, boolean vargs)
{
String ls = "xdc_runtime_Log_";
boolean lflg = (kind != FxnKind.ROM_E) && fxn.isLoggable();
String prefix = glob.cname + fxn.getName();
String en = prefix + (fxn.isVarg() && !vargs ? "_va" : "") + "__E";
String rn = prefix + (fxn.isVarg() && !vargs ? "_va" : "") + "__R";
String fn = prefix + (fxn.isVarg() ? "_va" : "") + "__F";
boolean ret = !(glob.isVoid(fxn));
if (kind == FxnKind.ROM_E && ptab == 1) {
fn = glob.cname + "Module__MTAB__C." + fxn.getName();
}
else if (kind == FxnKind.RAM_E && patch != null) {
fn = patch;
}
/* generate the __E (or __R) declaration */
String dn = fxn.getName() + (fxn.isVarg() && !vargs ? "_va" : "") + (kind == FxnKind.ROM_R ? "__R" : "__E");
glob.genTitleD(dn);
glob.genType(fxn.getType(), Glob.Type$TYP,
kind == FxnKind.ROM_R ? rn : en);
glob.out.print("(");
String sp = " ";
if (fxn.isInst()) {
glob.out.printf(" %1Handle __inst", glob.cname);
sp = ", ";
}
glob.genArgDecls(fxn.getArgs(), Glob.Type$LCL, sp);
glob.out.printf("%1 ) \n{\n%+",
vargs ? ", ..." : fxn.isVarg() ? ", va_list __va" : "");
/* start generating the function body */
/* if there is a return value, declare __ret to hold it */
if (ret && (vargs || (lflg && (mask & L_EXIT) != 0))) {
glob.out.tab();
glob.genType(fxn.getType(), Glob.Type$TYP, "__ret;\n");
skip();
}
/* if it's a vararg function, declare a va_list __va and "start" it */
if (vargs) {
Decl.Arg lastArg = fxn.getArgs().get(fxn.getArgs().size() - 1);
glob.out.printf("%tva_list __va; va_start(__va, %1);\n",
lastArg.getName());
}
// TODO factor into common genLog(); symbolize logging masks
/* generate entry trace */
if (!vargs && lflg && (mask & L_ENTRY) != 0) {
int argc = fxn.isInst() ? 1 : 0;
for (Decl.Arg arg : fxn.getArgs()) {
if (glob.fmtSpec(arg).length() == 0) {
break;
}
argc++;
}
if (argc > Glob.LOGARGS) {
argc = Glob.LOGARGS;
}
glob.out.printf("%t%3write%4(%1%2__ENTRY_EVT",
glob.cname, fxn.getName(), ls, argc);
if (fxn.isInst()) {
glob.out.printf(", (xdc_IArg)__inst");
--argc;
}
for (int i = 0; i < argc; i++) {
glob.out.printf(", (xdc_IArg)%1", fxn.getArgs().get(i).getName());
}
glob.out.printf(");\n");
}
/* call with exit trace */
if (lflg && (mask & L_EXIT) != 0) {
/* call fn */
glob.out.printf("%t%1%2(", ret ? "__ret = " : "", fn);
sp = "";
if (fxn.isInst()) {
glob.out.printf("(void*)__inst");
sp = ", ";
}
glob.genArgNames(fxn.getArgs(), sp);
glob.out.printf("%1);\n", fxn.isVarg() ? ", __va" : "");
/* "end" any varargs */
if (vargs) {
glob.out.printf("%tva_end(__va);\n");
}
/* generate Log exit event with the fn return value */
glob.out.printf("%t%3write1(%1%2__EXIT_EVT, %4);\n",
glob.cname, fxn.getName(), ls,
ret ? "(xdc_IArg)__ret" : "0");
if (ret) {
glob.out.printf("\n%treturn __ret;\n");
}
}
/* call fn without exit trace */
else {
glob.out.printf("%t%1%2(",
(vargs && ret) ? "__ret = " : ret ? "return " : "", fn);
sp = "";
if (fxn.isInst()) {
glob.out.printf("(void*)__inst");
sp = ", ";
}
glob.genArgNames(fxn.getArgs(), sp);
glob.out.printf("%1);\n", fxn.isVarg() ? ", __va" : "");
/* "end" any varargs */
if (vargs) {
glob.out.printf("\n%tva_end(__va);\n");
if (ret) {
glob.out.printf("%treturn __ret;\n");
}
}
}
/* close the body of __E (or __R) */
glob.out.printf("}\n%-");
}
/*
* ======== genFxnDeleg ========
*/
private void genFxnDeleg( Unit unit, Decl.Fxn fxn )
{
String en = glob.cname + fxn.getName() + "__E";
String dn = glob.mkCname(unit.delegatesTo().getQualName()) + fxn.getName() + "__E";
String ls = "xdc_runtime_Log";
boolean ret = !(glob.isVoid(fxn));
glob.genType(fxn.getType(), Glob.Type$TYP, en);
glob.out.print("(");
String sp = " ";
if (fxn.isInst()) {
glob.out.printf(" %1Handle __inst", glob.cname);
sp = ", ";
}
glob.genArgDecls(fxn.getArgs(), Glob.Type$LCL, sp);
glob.out.printf(" ) {\n%+");
if (ret) {
glob.out.tab();
glob.genType(fxn.getType(), Glob.Type$TYP, "__ret;\n");
}
glob.out.printf("%t%1%2(", !glob.isVoid(fxn) ? "__ret = " : "", dn);
sp = "";
if (fxn.isInst()) {
glob.out.printf("%1Object_delegate((%1Object*)__inst)", glob.cname);
sp = ", ";
}
glob.genArgNames(fxn.getArgs(), sp);
glob.out.printf("%1);\n", fxn.isVarg() ? ", __va" : "");
if (ret) {
glob.out.printf("%treturn __ret;\n");
}
glob.out.printf("}\n%-");
}
/*
* ======== genFxnStubs ========
* Generate the __E (or __R) function stubs for functions in unit.
*/
private void genFxnStubs(Value.Obj mod, FxnKind kind)
{
Unit unit = unitSpec(mod);
if (unit.isProxy()) {
return;
}
HashMap<String,String> pmap = null;
if (kind == FxnKind.RAM_E && mod.has("$$patchsyms", null)) {
pmap = new HashMap();
String[] psarr = mod.gets("$$patchsyms").split(";");
for (String ps : psarr) {
String[] sa = ps.split("=");
pmap.put(sa[0], sa[1]);
}
}
if (mod.geti("$$scope") == -1 && pmap == null) {
return;
}
boolean first = true;
int mask = commonGetv(mod, "logger") != null ? mod.geti("Module__diagsIncluded") : 0;
int ptab = kind == FxnKind.ROM_E ? commonGeti(mod, "romPatchTable") : 0;
for (Decl.Fxn fxn : unit.getFxns()) {
if (fxn.isMeta() || fxn.isSys()
|| fxn.attrBool(Attr.A_Macro) || fxn.attrBool(Attr.A_DirectCall)) {
continue;
}
String patch = null;
if (pmap != null && ((patch = pmap.get(fxn.getName())) == null)) {
continue;
}
if (first) {
genTitle(mod, "FUNCTION STUBS");
if (kind != FxnKind.ROM_R && mask != 0) {
glob.genModuleDefines();
genModLog(mod);
}
first = false;
}
if ((unit.delegatesTo() != null && fxn.getParent() != unit)) {
genFxnDeleg(unit, fxn);
}
else {
/* vararg functions need to be generated twice:
* first we generate a fix arg stub that takes a va_list arg
* and calls the va_list implementation
*
* the second uses "..." converts to va_list and also calls
* the va_list implementation
*/
genFxnBody(unit, fxn, kind, mask, ptab, patch, false);
if (fxn.isVarg()) {
genFxnBody(unit, fxn, kind, mask, ptab, patch, true);
}
}
}
if (unit.attrBool(Attr.A_ModuleStartup) && !unit.isProxy()) {
String fn = glob.cname + "Module_startup";
if (kind != FxnKind.ROM_R && mod.geti("$$scope") != -1) {
glob.genTitleD("Module_startup");
glob.out.printf("xdc_Int %1__E( xdc_Int state )\n{\n%+%treturn %1__F(state);\n}\n%-", fn);
}
}
}
/*
* ======== genFxnTabM ========
*/
private void genFxnTabM( Value.Obj mod )
{
if (commonGeti(mod, "romPatchTable") == 0) {
return;
}
Unit unit = unitSpec(mod);
if (unit.isInter() || unit.isProxy()) {
return;
}
if (!isrom && mod.geti("$$scope") != -1) {
return;
}
genTitle(mod, "PATCH TABLE");
String tn = "Module__MTAB__C";
genRomSect(glob.cname, tn, 'C');
if (isrom) {
glob.out.printf("__FAR__ const %1MTab__ %1%2;\n", glob.cname, tn);
}
else {
glob.out.printf("__FAR__ const %1MTab__ %1%2 = {\n%+", glob.cname, tn);
for (Decl.Fxn fxn : unit.getAllFxns()) {
if (fxn.isMeta() || fxn.isSys() || fxn.overrides() != null) {
continue;
}
if (fxn.attrBool(Attr.A_Macro) || fxn.attrBool(Attr.A_DirectCall)) {
continue;
}
glob.out.printf("%t%1%2%3__E,\n", glob.cname, fxn.getName(), (fxn.isVarg() ? "_va" : ""));
}
glob.out.printf("%t0\n");
glob.out.printf("%-%t};\n");
}
}
/*
* ======== genFxnTabV ========
*/
void genFxnTabV(Value.Obj mod)
{
Unit unit = unitSpec(mod);
if (unit.isProxy() || !isasm(mod)) {
return;
}
if (!unit.isHeir()) {
return;
}
if (commonGeti(mod, "fxntab") != 1) {
return;
}
if (mod.geti("$$scope") == -1) {
return;
}
genTitle(mod, "VTABLE");
String tn = "Module__FXNS__C";
String cn = glob.mkCname(unit.getQualName());
clink(cn + tn);
glob.genTitleD(tn);
glob.out.printf("const %1Fxns__ %1%2 = {\n%+", cn, tn);
glob.out.printf("%t"); glob.genBase(unit.getSuper()); glob.out.printf(", /* base__ */\n");
glob.out.printf("%t&%1%2.__sfxns, /* __sysp */\n", cn, tn);
for (Decl.Fxn fxn : unit.getAllFxns()) {
if (fxn.isMeta() || fxn.isSys() || fxn.overrides() != null) {
continue;
}
if (unit.isMod() && fxn.getParent().isMod()) {
continue;
}
glob.out.printf("%t%1%2%3,\n", cn, fxn.getName(), fxn.isVarg() ? "_va" : "__E");
}
glob.out.printf("%t{\n%+");
int pol = commonGeti(mod, "memoryPolicy");
if (unit.getCreator() != null && pol != STATIC_POLICY) {
glob.out.printf("%t%1Object__create__S,\n", cn);
}
else {
glob.out.printf("%tNULL, /* __create */\n");
}
if (unit.isInst() && pol == DELETE_POLICY) {
glob.out.printf("%t%1Object__delete__S,\n", cn);
glob.out.printf("%t%1Handle__label__S,\n", cn);
}
else {
glob.out.printf("%tNULL, /* __delete */\n");
glob.out.printf("%tNULL, /* __label */\n");
}
glob.out.printf("%t%1, /* __mid */\n", String.format("0x%x", mod.geti("Module__id")));
glob.out.printf("%-%t} /* __sfxns */\n");
glob.out.printf("%-%t};\n");
}
/*
* ======== genGlobals ========
*/
void genGlobals(Value prog, Out out)
{
glob.mode = Glob.CDLMODE;
glob.out = out;
genGlobals(prog, true);
}
void genGlobals(Value prog, boolean hdr)
{
if (hdr) {
glob.genWarning();
skip();
glob.out.printf("#include <xdc/std.h>\n\n");
}
Value gmap = prog.getv("global");
String sect = prog.gets("globalSection");
Object[] keys = gmap.getIds();
for (int i = 0; i < keys.length; i++) {
String errMsg = null;
String vname = (String)keys[i];
Object oval = gmap.get(vname, gmap);
if (oval instanceof Value.Obj) {
Value.Obj vobj = ((Value.Obj)oval);
String tname = vobj.getProto().tname();
if (otype(tname) == INST) {
String qn = tname.substring(0, tname.lastIndexOf('.'));
String cs = qn.replace('.', '_');
String ts = cs + "_Handle";
if (hdr) {
glob.out.printf("#include <%1.h>\n", glob.mkFname(qn));
glob.out.printf("extern const %1 %2;\n", ts, vname);
}
else {
if (sect != null) {
glob.out.printf("#ifdef __ti__sect\n");
glob.out.printf("%+%t#pragma DATA_SECTION(%1, \"%2\");\n%-",
vname, sect);
glob.out.printf("#endif\n");
}
glob.out.printf("#ifdef __GNUC__\n#if __GNUC__ >= 4\n");
glob.out.printf("%+%t__attribute__ ((externally_visible))\n%-");
glob.out.printf("#endif\n#endif\n");
glob.out.printf("const %1 %2 = (%1)(%3);\n", ts, vname,
valToStr(vobj.getOrig()));
}
}
else {
errMsg = "Program.global." + vname
+ " (of type " + oval.getClass().toString()
+ "): not an Instance";
}
}
// TODO add section placement for Value.Arr and Ptr externs
else if (oval instanceof Value.Arr) {
Value.Arr arr = (Value.Arr)oval;
if (hdr) {
String qn = val2mod(arr);
glob.out.printf("#include <%1.h>\n", glob.mkFname(qn));
glob.out.printf("extern const %1* %2;\n", arr.getCtype(), vname);
}
else {
glob.out.printf("const %1* %2 = %3;\n", arr.getCtype(), vname, aname(arr));
}
}
else if (oval instanceof java.lang.String) {
if (hdr) {
glob.out.printf("#define %1 \"%2\"\n", vname, oval);
}
}
else if (oval instanceof java.lang.Boolean) {
if (hdr) {
glob.out.printf("#define %1 %2\n", vname,
((java.lang.Boolean)oval).booleanValue() ? "1" : "0");
}
}
else if (oval instanceof java.lang.Number) {
if (hdr) {
glob.out.printf("#define %1 %2\n", vname,
Proto.Elm.numval((Number)oval));
}
}
else if (oval instanceof Ptr) {
if (hdr) {
glob.out.printf("extern const void* %1;\n", vname);
}
else {
glob.out.printf("const void* %1 = %2;\n", vname, ptrToStr(oval));
}
}
else {
errMsg = "Program.global." + vname
+ " (of type " + oval.getClass().toString()
+ "): unsupported generation type";
}
if (errMsg != null) {
xdc.services.intern.xsr.Err.exit(errMsg);
return;
}
glob.out.printf("\n");
}
}
/*
* ======== genInclude ========
*/
private void genInclude(Value.Obj mod)
{
Unit u = unitSpec(mod);
if (u.isProxy()) {
return;
}
glob.out.printf("#include <%1.h>\n", glob.mkFname(u.getQualName()));
}
/*
* ======== genInherits ========
*/
private void genInherits( Unit iu, int scope )
{
if (iu == null) {
return;
}
if (!baseset.add(iu.getQualName())) {
return;
}
genInherits(iu.getSuper(), scope);
String cname = glob.mkCname(iu.getQualName());
String iname = glob.mkIname(iu.getQualName());
String bs = "Interface__BASE__C";
if (isrom || scope == -1 || romset.contains(iu.getQualName())) {
genRomSect(cname, bs, 'C');
}
else {
clink(cname + bs);
}
if (isrom) {
glob.out.printf("__FAR__ const xdc_runtime_Types_Base %1%2;\n", cname, bs);
}
else {
glob.out.printf("__FAR__ const xdc_runtime_Types_Base %1%2 = {", cname, bs);
glob.genBase(iu.getSuper());
glob.out.printf("};\n");
}
}
/*
* ======== genInstDecls ========
*/
private void genInstDecls(Value.Obj mod, Unit u)
{
String cname = glob.mkCname(u.getQualName());
if (mod == null || !modset.add(mod)) {
glob.genTitleD("<-- " + cname + "Object");
return;
}
for (Unit ud : u.getEmbeds()) {
if (ud != u && !ud.isMeta() && ud.isInst() && ud.isMod()) {
genInstDecls(modmap.get(ud.getQualName()), ud);
}
}
int kind = iobjKind(mod);
String pre = glob.curUnit == u ? "" : ("@@@ " + cname);
if (kind == IOBJ_BASIC || kind == IOBJ_DLGST) {
glob.genTitleD(pre + "Object__");
String vs = cname + "__VERS";
glob.out.printf("%ttypedef struct %1Object__ {%+\n", cname);
glob.genStateFlds(u, true);
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%txdc_runtime_Types_CordAddr __name;\n");
}
glob.out.printf("%-%t} %1Object__;\n", cname);
}
else if (kind == IOBJ_PROXY) {
Value.Obj delmod = ((Value.Obj)(mod.getv("delegate$"))).getOrig();
Unit du = unitSpec(delmod);
genInstDecls(delmod, du);
glob.genTitleD(pre + "Object");
glob.out.printf("typedef %1Object__ %2Object__;\n",
glob.mkCname(du.getQualName()), cname);
}
else { // kind == IOBJ_DLGPR
Value.Obj delmod = modDeleg(mod);
Unit du = unitSpec(delmod);
genInstDecls(delmod, du);
String dcname = glob.mkCname(du.getQualName());
glob.genTitleD(pre + "Object");
glob.out.printf("struct %1Object {%+\n", cname);
glob.genStateFlds(u, true);
glob.out.printf("%t%1Object __deleg;\n", dcname);
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%txdc_runtime_Types_CordAddr __name;\n");
}
glob.out.printf("%-};\n", cname);
glob.genTitleD(pre + "Object__");
glob.out.printf("typedef %1Object %1Object__;\n", cname);
}
glob.genTitleD(pre + "Object2__");
glob.out.printf("typedef struct {%+\n");
glob.out.printf("%txdc_runtime_Types_InstHdr hdr;\n");
glob.out.printf("%t%1Object__ obj;\n", cname);
glob.out.printf("%-} %1Object2__;\n", cname);
}
/*
* ======== genInstObj ========
*/
private void genInstObj(Value.Obj iobj, Value.Obj mod, String cname)
{
if (mod.geti("$$iflag") == 1) {
if (commonGeti(mod, "fxntab") == 1) {
glob.out.printf("%t&%1Module__FXNS__C,\n", cname);
}
else {
glob.out.printf("%t0,\n", cname);
}
}
genFlds(iobj);
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%t%1 /* __name */\n", genCordAddr(iobj.geti("__name")));
}
}
/*
* ======== genInternals ========
*/
private void genInternals(Value.Obj mod)
{
Unit unit = unitSpec(mod);
genTitle(mod, "INTERNALS");
genModDecls(mod, unit);
if (unit.isInst()) {
genInstDecls(mod, unit);
genFixup(mod, unit);
}
}
/*
* ======== genMod ========
*/
private void genMod(Value.Obj mod)
{
Unit u = unitSpec(mod);
if (mode == VALMODE) {
pkgset.add(mod.getv("$package").gets("$$qn"));
}
if (u.isProxy()) {
return;
}
genModInsts(mod, u);
genModState(mod, u);
genModConfigs(mod, u);
}
/*
* ======== genModConfigs ========
*/
private void genModConfigs(Value.Obj mod, Unit unit)
{
if (!isrom) {
genPreds(mod, "", "", true);
}
if (mode == DCLMODE) {
return;
}
String ts = mod.getProto().tname();
String iname = glob.mkIname(ts.substring(0, ts.lastIndexOf('.')));
int scope = mod.geti("$$scope");
String romcfgs = mod.gets("$$romcfgs");
int inscnt = unit.isInst() && !unit.isProxy() ? mod.getv("$instances").geti("length") : 0;
for (Member fld : mod.getProto().allFlds()) {
if (fld.isMeta() || fld.getName().startsWith("$")) {
continue;
}
String fn = iname + fld.getName();
Object fldval = mod.get(fld.getName(), mod);
if (undef(fldval)) {
mod.error("property '" + fld.getName() + "' is undefined");
continue;
}
boolean rommed = romcfgs.indexOf("|" + fld.getName() + '|') != -1;
if (scope == -1 && rommed) {
continue;
}
if ((isrom || scope == -1) && !rommed) {
genRomSect(iname, fld.getName() + "__C", 'C');
}
else {
clink(iname + fld.getName() + "__C");
}
glob.genTitleD(fld.getName() + "__C");
glob.out.printf("__FAR__ const CT__%1 %1__C", fn);
if (!isrom || rommed) {
glob.out.printf(" = ");
if (fld.getName().equals("Object__sizeof")) {
if (unit.isInst()) {
glob.out.printf("sizeof(%1Object__)", glob.cname);
}
else {
glob.out.printf("0");
}
}
else if (fld.getName().equals("Object__count")) {
glob.out.printf("%1", Integer.toString(inscnt));
}
else if (fld.getName().equals("Object__table")) {
glob.out.printf("%1", inscnt > 0 ? (glob.cname + "Object__table__V") : "0");
}
else if (fld.getName().equals("Object__heap")) {
Value.Obj vref = (Value.Obj)commonGetv(mod, "instanceHeap");
glob.out.printf("%1", vref != null ? valToStr(vref) : "0");
}
else {
genVal(fld.getProto(), fldval, "CT__" + fn);
}
}
glob.out.printf(";\n");
}
}
/*
* ======== genModDecls ========
*/
private void genModDecls(Value.Obj mod, Unit u)
{
String cname = glob.mkCname(u.getQualName());
boolean ihdr = u.isInst() && commonGeti(mod, "memoryPolicy") != STATIC_POLICY;
boolean lhdr = hasLogHdr(mod);
if (ihdr || lhdr) {
glob.genTitleD("Module__");
glob.out.printf("typedef struct %1Module__ {\n%+", cname);
if (ihdr) {
glob.out.printf("%txdc_runtime_Types_Link link;\n");
}
if (lhdr) {
glob.out.printf("%txdc_runtime_Types_DiagsMask mask;\n");
}
glob.out.printf("%-} %1Module__;\n", cname);
glob.genTitleD("Module__root__V");
glob.out.printf("extern %1Module__ %1Module__root__V;\n", cname);
}
if (commonGeti(mod, "romPatchTable") == 0) {
return;
}
glob.genTitleD("MTab__");
glob.out.printf("typedef struct %1MTab__ {\n%+", cname);
genModFxns(u);
glob.out.printf("%txdc_Char __dummy;\n", cname);
glob.out.printf("%-} %1MTab__;\n", cname);
}
/*
* ======== genModDesc ========
*/
private void genModDesc(Value.Obj mod, String cname, int scope)
{
if (mode == DCLMODE) {
return;
}
String ds = "Object__DESC__C";
boolean hasHeap = commonGetv(mod, "instanceHeap") != null;
if (!hasHeap && scope == -1) {
return;
}
if (hasHeap && (isrom || scope == -1)) {
genRomSect(cname, ds, 'C');
}
else {
clink(cname + ds);
}
glob.genTitleD(ds);
glob.out.printf("__FAR__ const xdc_runtime_Core_ObjDesc %1%2;\n", cname, ds);
}
/*
* ======== genModFxns ========
*/
private void genModFxns(Unit u)
{
boolean sysFlg = u.getQualName().equals("xdc.runtime.Types");
for (Decl.Fxn fxn : u.getAllFxns()) {
if (fxn.isMeta() || fxn.overrides() != null) {
continue;
}
if (fxn.attrBool(Attr.A_Macro) || fxn.attrBool(Attr.A_DirectCall)) {
continue;
}
if (fxn.isSys() != sysFlg) {
continue;
}
if (fxn.isSys() && fxn.isVarg()) {
continue;
}
glob.out.tab();
glob.genType(fxn.getType(), Glob.Type$PTR);
glob.out.print("(");
String sp = " ";
if (fxn.isInst()) {
glob.out.printf(" %1Handle", glob.cname);
sp = ", ";
}
glob.genArgDecls(fxn.getArgs(), Glob.Type$ABS, sp);
if (fxn.isVarg()) {
glob.out.printf(", va_list ");
}
glob.out.printf(");\n");
}
}
/*
* ======== genModInherits ========
*/
private void genModInherits(Value.Obj mod, boolean populate)
{
Unit u = unitSpec(mod);
if (u.isMeta() || !isasm(mod) || u.isProxy()) {
return;
}
if (!u.isHeir()) {
return;
}
if (commonGeti(mod, "fxntab") != 1) {
return;
}
if (populate) {
if (mod.geti("$$scope") == -1) {
for (Unit iu : u.getInherits()) {
romset.add(iu.getQualName());
}
}
}
else {
genTitle(mod, "INHERITS");
genInherits(u.getSuper(), mod.geti("$$scope"));
skip();
}
}
/*
* ======== genModInsts ========
*/
private void genModInsts(Value.Obj mod, Unit u)
{
if (!u.isInst()) {
return;
}
boolean ihdr = commonGeti(mod, "memoryPolicy") != STATIC_POLICY;
boolean lhdr = hasLogHdr(mod);
String cname = glob.mkCname(u.getQualName());
int scope = mod.geti("$$scope");
genModDesc(mod, cname, scope);
genModParams(mod, cname, scope);
if (isrom) {
if (mode == DCLMODE) {
if (ihdr || lhdr) {
genRomSect(cname, "Module__root__V", 'V');
glob.genTitleD("Module__root__V");
glob.out.printf("%1Module__ %1Module__root__V;", cname);
}
}
return;
}
Value insarr = mod.getv("$instances");
int inscnt = insarr.geti("length");
for (int i = 0; i < inscnt; i++) {
Value.Obj inst = (Value.Obj)insarr.getv(i);
genPreds((Value.Obj)inst.getv("$object"),
"", "Instance_State__", false);
}
boolean noInsts = (inscnt == 0) || (mod.geti("PROXY$") != 0);
if (mode == VALMODE && (ihdr || lhdr)) {
String rn = cname + "Module__root__V";
if (scope == -1) {
genRomSect(cname, "Module__root__V", 'V');
}
glob.genTitleD("Module__root__V");
glob.out.printf("%1Module__ %2 = {\n%+", cname, rn);
if (ihdr) {
glob.out.printf("%t{&%1.link, /* link.next */\n", rn);
glob.out.printf("%t&%1.link}, /* link.prev */\n", rn);
}
if (lhdr) {
glob.out.printf("%t%1, /* mask */\n", Integer.toString(mod.geti("$$diagsMask")));
}
glob.out.printf("%-};\n");
// TODO: anomaly with lack of instance$static$init and "empty" instances
}
if (noInsts) {
return;
}
String instSect = commonGets(mod, "instanceSection");
if (mode == DCLMODE && instSect != null) {
glob.out.printf("#ifdef __ti__sect\n");
glob.out.printf("%+%t#pragma DATA_SECTION(%1Object__table__V, \"%2\");\n%-", cname, instSect);
glob.out.printf("#endif\n");
}
glob.genTitleD("Object__table__V");
glob.out.printf("%1Object__ %1Object__table__V[%2]", cname, Integer.toString(inscnt));
if (mode == DCLMODE) {
glob.out.printf(";\n");
return;
}
int kind = iobjKind(mod);
glob.out.printf(" = {\n%+");
for (int i = 0; i < inscnt; i++) {
Value.Obj iobj = (Value.Obj)insarr.getv(i).getv("$object");
glob.out.printf("%t{/* instance#%1 */\n%+", Integer.toString(i));
if (kind == IOBJ_PROXY) {
Value.Obj dobj = (Value.Obj)iobj.getv("$delegate");
Value.Obj dmod = ((Value.Obj)mod.getv("delegate$")).getOrig();
String dcname = glob.mkCname(dmod.gets("$name"));
genInstObj(dobj, dmod, dcname);
}
else if (kind == IOBJ_DLGST) {
genInstObj(iobj, mod, cname);
Value.Obj dobj = (Value.Obj)iobj.getv("$delegate").getv("$object");
Value.Obj dmod = ((Value.Obj)mod.getv("delegate$")).getOrig();
String dcname = glob.mkCname(dmod.gets("$name"));
int dkind = iobjKind(dmod);
glob.out.printf("%t{/* __deleg */\n%+", Integer.toString(i));
genInstObj(dobj, dmod, dcname);
glob.out.printf("%-%t},\n");
}
else if (kind == IOBJ_DLGPR) {
genInstObj(iobj, mod, cname);
Value.Obj dobj = (Value.Obj)iobj.getv("$delegate").getv("$object");
Value.Obj dmod = ((Value.Obj)mod.getv("delegate$")).getOrig();
dobj = (Value.Obj)dobj.getv("$delegate");
dmod = ((Value.Obj)dmod.getv("delegate$")).getOrig();
String dcname = glob.mkCname(dmod.gets("$name"));
int dkind = iobjKind(dmod);
glob.out.printf("%t{/* __deleg */\n%+", Integer.toString(i));
genInstObj(dobj, dmod, dcname);
glob.out.printf("%-%t},\n");
}
else {
genInstObj(iobj, mod, cname);
}
glob.out.printf("%-%t},\n");
}
glob.out.printf("%-};\n");
}
/*
* ======== genModLog ========
*/
private void genModLog(Value.Obj mod)
{
if (mod.has("$$fxnEvtIds", mod)) {
glob.genTitleD("entry/exit Log events");
String evtIds = mod.gets("$$fxnEvtIds");
if (evtIds != null) {
for (String eid : evtIds.split(",")) {
String[] sa = eid.split(":");
glob.out.printf("#define %1%2__ENTRY_EVT %3\n",
glob.cname, sa[0], String.format("0x%x", Long.parseLong(sa[1])));
glob.out.printf("#define %1%2__EXIT_EVT %3\n",
glob.cname, sa[0], String.format("0x%x", Long.parseLong(sa[2])));
}
}
}
}
/*
* ======== genModParams ========
*/
private void genModParams(Value.Obj mod, String cname, int scope)
{
boolean defer = mod.gets("$$romcfgs").indexOf("|Object__PARAMS|") == -1;
if (!defer && scope == -1) {
return;
}
String ps = "Object__PARAMS__C";
if (defer && isrom || scope == -1) {
genRomSect(cname, ps, 'C');
}
else {
clink(cname + ps);
}
if (isrom && defer) {
glob.genTitleD(ps);
glob.out.printf("__FAR__ const %1Params %1%2;\n", cname, ps);
}
else {
Value.Obj prms = (Value.Obj)mod.getv("PARAMS");
genPreds(prms, "", "", true);
if (mode == VALMODE) {
glob.genTitleD(ps);
glob.out.printf("__FAR__ const %1Params %1%2 = {\n%+", cname, ps);
glob.out.printf("%tsizeof (%1Params), /* __size */\n", cname);
glob.out.printf("%t0, /* __self */\n", cname, ps);
glob.out.printf("%t0, /* __fxns */\n");
glob.out.printf("%t(xdc_runtime_IInstance_Params*)&%1%2.__iprms, /* instance */\n",
cname, ps);
genFlds(prms);
glob.out.printf("%-};\n");
}
}
}
/*
* ======== genModState ========
*/
private void genModState(Value.Obj mod, Unit u)
{
String cname = glob.mkCname(u.getQualName());
boolean lhdr = hasLogHdr(mod);
int scope = mod.geti("$$scope");
if (mode == VALMODE && !u.isInst() && lhdr) {
if (isrom || scope == -1) {
genRomSect(cname, "Module__root__V", 'V');
}
glob.genTitleD("Module__root__V");
glob.out.printf("%1Module__ %1Module__root__V", cname);
if (!isrom) {
glob.out.printf(" = {\n%+%t%1, /* mask */\n%-}",
Integer.toString(mod.geti("$$diagsMask")));
}
glob.out.printf(";\n");
}
Value.Obj vobj = (Value.Obj)mod.getv("$object");
if (vobj == null) {
return;
}
if (mode == DCLMODE) {
glob.genTitleD("Module_State__");
glob.out.printf("typedef struct %1Module_State__ {%+\n", cname);
glob.genStateFlds(u, false);
glob.out.printf("%-} %1Module_State__;\n", cname);
}
if (isrom) {
if (mode == DCLMODE) {
genRomSect(cname, "Module__state__V", 'V');
glob.genTitleD("Module__state__V");
glob.out.printf("%1Module_State__ %1Module__state__V;\n", cname);
}
return;
}
genPreds(vobj, "", "Module_State__", false);
if (scope == -1) {
genRomSect(cname, "Module__state__V", 'V');
}
glob.genTitleD("Module__state__V");
glob.out.printf("%1Module_State__ %1Module__state__V", cname);
if (mode == DCLMODE) {
glob.out.printf(";\n");
}
else {
glob.out.printf(" = {\n%+");
genFlds(vobj);
glob.out.printf("%-};\n");
}
}
/*
* ======== getOffsets ========
*/
void genOffsets( Value.Obj mod )
{
if (mod.geti("$$scope") == -1) {
return;
}
Unit unit = unitSpec(mod);
List<Decl.Field> fL = glob.offsetFlds(unit);
if (fL.size() == 0) {
return;
}
glob.genTitle("OBJECT OFFSETS");
for (Decl.Field fld : fL) {
String sn = fld.getParent().getName();
xdc.services.spec.Ref r = glob.rawType(fld.getType()).tspec().getRef();
String on = glob.cname + sn + '_' + fld.getName() + "__O";
clink(on);
sn = sn.equals("Module_State") ? (sn += "__") : "Object__";
glob.out.printf("__FAR__ const xdc_SizeT %1 = offsetof(%2%3, Object_field_%4);\n",
on, glob.cname, sn, fld.getName());
}
skip();
}
/*
* ======== getPkgAliases ========
*/
private void getPkgAliases(Value.Obj po, HashMap<String,Value.Obj> modmap,
Hashtable<String,String> aliases)
{
Pkg pkg = pkgSpec(po); /* get spec object for the config pkg value */
/* scan the package spec for runtime modules */
for (Unit unit: pkg.getUnits()) {
if (!unit.isMeta() && !unit.isProxy()
&& !unit.isInter() && unit.needsRuntime()) {
glob.setNames(unit);
/* get config module object from modvec */
Value.Obj mod = modmap.get(unit.getQualName());
if (mod == null || !isasm(mod)) {
continue; /* unit is not part of the configuration */
}
/* get mod's Diags mask and logger */
int mask = 0;
Object loggerObj = null;
if (mod.has("Module__diagsIncluded", mod)) {
mask = mod.geti("Module__diagsIncluded");
loggerObj = commonGetv(mod, "logger");
}
else {
// System.glob.out.println("Warning: "
// + mod.gets("$name") + " does not have diags");
continue;
}
/* scan all functions in the module's spec */
for (Decl.Fxn fxn : unit.getFxns()) {
if (fxn.isMeta() || fxn.isSys()
|| fxn.attrBool(Attr.A_Macro)
|| fxn.attrBool(Attr.A_DirectCall)) {
continue;
}
if ((unit.delegatesTo() != null
&& fxn.getParent() != unit)) {
continue;
}
/* if there is no logging for fxn, it's an alias */
if (!fxn.isLoggable()
|| loggerObj == null || undef(loggerObj)
|| (mask & 0x3) == 0) {
String prefix = glob.cname + fxn.getName()
+ (fxn.isVarg() ? "_va" : "");
aliases.put(prefix + "__E", prefix + "__F");
}
}
}
}
}
/*
* ======== genPostInit ========
*/
private void genPostInit()
{
if (mInitCnt == 0) {
return;
}
glob.genTitle("INITIALIZATION ENTRY POINT");
glob.out.printf("extern int __xdc__init(void);\n");
glob.out.printf("#ifdef __GNUC__\n#if __GNUC__ >= 4\n");
glob.out.printf("%+%t__attribute__ ((externally_visible))\n%-");
glob.out.printf("#endif\n#endif\n");
glob.out.printf("__FAR__ int (* volatile __xdc__init__addr)(void) = &__xdc__init;\n");
skip();
}
/*
* ======== genPragmas ========
*/
void genPragmas( Value.Obj mod )
{
Unit unit = unitSpec(mod);
// TODO: generalize to use all system functions
if (unit.isProxy()) {
return;
}
genTitle(mod, "PRAGMAS");
String fmt = "%+%t#pragma FUNC_EXT_CALLED(" + glob.cname + "%1);\n%-";
int scope = mod.geti("$$scope");
if (isrom || (scope == 1)) {
glob.out.printf("\n#ifdef __ti__\n", glob.cname);
glob.out.printf(fmt, "Module__startupDone__S");
if (unit.isInst()) {
glob.out.printf(fmt, "Handle__label__S");
glob.out.printf(fmt, "Object__create__S");
glob.out.printf(fmt, "Object__delete__S");
glob.out.printf(fmt, "Object__destruct__S");
glob.out.printf(fmt, "Object__get__S");
glob.out.printf(fmt, "Object__first__S");
glob.out.printf(fmt, "Object__next__S");
glob.out.printf(fmt, "Params__init__S");
}
if (unit.attrBool(Attr.A_ModuleStartup) && !unit.isProxy()) {
glob.out.printf(fmt, "Module_startup__E");
}
for (Decl.Fxn fxn : unit.getFxns()) {
if (fxn.attrBool(Attr.A_DirectCall)) {
String fn = glob.cname + fxn.getName() + "__E";
clink(fn + 'D');
glob.out.printf(
"%+%tconst xdc_IArg %1D = (xdc_IArg)&%1;\n%-", fn);
continue;
}
if (fxn.attrBool(Attr.A_Macro)) {
continue;
}
if (!fxn.isMeta() && !fxn.isSys()) {
String suf = !isrom ? "__E" : "__R";
glob.out.printf(fmt, fxn.getName() + suf);
if (isrom && fxn.isVarg()) {
glob.out.printf(fmt, fxn.getName() + "_va__R");
}
}
}
glob.out.printf("#endif\n");
}
if (isrom) {
return;
}
/*
if (scope != -1 && mod.getv("$object") != null) {
String ns = glob.cname + "Module__state__V";
glob.out.printf("\n#ifdef __ti__\n", glob.cname);
glob.out.printf("#pragma DATA_SECTION(%1, \".bss:%1\");\n", ns);
glob.out.printf("%tasm(\"\t.sect \\\".bss:%1\\\"\");\n", ns);
glob.out.printf("%tasm(\"\t .clink\");\n");
glob.out.printf("#endif\n");
}
*/
glob.out.printf("\n#ifdef __GNUC__\n#if __GNUC__ >= 4\n%+", glob.cname);
for (Decl.Config cfg : unit.getConfigs()) {
if (cfg.isInst() || cfg.isMeta()) {
continue;
}
glob.out.printf("%tconst CT__%1 %1__C __attribute__ ((externally_visible));\n",
glob.cname + cfg.getName());
}
for (Decl.Fxn fxn : unit.getFxns()) {
if (fxn.isMeta() || fxn.attrBool(Attr.A_Macro)
|| fxn.attrBool(Attr.A_DirectCall)) {
continue;
}
String suf = fxn.isSys() ? "__S" : "__E";
glob.out.tab();
glob.genType(fxn.getType(), Glob.Type$TYP, glob.cname
+ fxn.getName() + suf);
glob.out.print("(");
String sp = " ";
if (fxn.isInst()) {
glob.out.printf(" %1Handle", glob.cname);
sp = ", ";
}
glob.genArgDecls(fxn.getArgs(), Glob.Type$LCL, sp);
if (fxn.isVarg()) {
glob.out.printf(", ...");
}
glob.out.printf(" ) __attribute__ ((externally_visible));\n");
}
glob.out.printf("%-#endif\n#endif\n");
}
/*
* ======== genPreds ========
*/
private void genPreds(Value.Obj vobj, String path, String scope, boolean isConst)
{
if (vobj == null) {
return;
}
if (vobj.getProto().tname().endsWith(".Object")) {
genPreds((Value.Obj)vobj.getv("$object"), "", "Instance_State__", false);
}
for (Member fld : vobj.getProto().allFlds()) {
if (fld.isMeta() || fld.getName().startsWith("$")) {
continue;
}
Object fldval = vobj.get(fld.getName(), vobj);
if (undef(fldval)) {
vobj.error("'" + fld.getName() + "' must be statically "
+ "initialized.");
continue;
}
if (!(fld.getProto() instanceof Proto.Pred)) {
continue;
}
String ps = path + '.' + fld.getName();
if (fld.getProto() instanceof Proto.Str) {
genPreds((Value.Obj)fldval, ps, scope, isConst);
}
else if (fldval instanceof Value.Arr) {
genArr((Value.Arr)fldval, scope + fld.getName(), vobj, ps, isConst);
}
else if (fldval instanceof Extern) {
genExt((Extern)fldval);
}
else if (fldval instanceof Value.Obj) {
genStruct((Value.Obj)fldval, isConst);
}
}
}
/*
* ======== genPrologue ========
*/
private void genPrologue()
{
glob.genWarning();
skip();
glob.out.printf("#define __nested__\n");
glob.out.printf("#define __config__\n");
skip();
glob.out.printf("#include <xdc/std.h>\n");
skip();
glob.genSections(
"",
"MODULE INCLUDES",
"",
"<module-name> INTERNALS",
"<module-name> INHERITS",
"<module-name> VTABLE",
"<module-name> PATCH TABLE",
"<module-name> DECLARATIONS",
"<module-name> OBJECT OFFSETS",
"<module-name> TEMPLATES",
"<module-name> INITIALIZERS",
"<module-name> FUNCTION STUBS",
"<module-name> PROXY BODY",
"<module-name> OBJECT DESCRIPTOR",
"<module-name> SYSTEM FUNCTIONS",
"<module-name> PRAGMAS",
"",
"INITIALIZATION ENTRY POINT",
"PROGRAM GLOBALS",
"CLINK DIRECTIVES"
);
skip();
}
/*
* ======== genProxy ========
*/
private void genProxy( Value.Obj mod, boolean isRom )
{
Unit unit = unitSpec(mod);
if (!unit.isProxy()) {
return;
}
genTitle(mod, "PROXY BODY");
Value delmod = mod.getv("delegate$");
String dcname = glob.mkCname(delmod.gets("$name"));
glob.genTitleD("DELEGATES TO " + delmod.gets("$name"));
String icn = glob.mkCname(unit.getSuper().getQualName());
glob.genTitleD("Module__startupDone__S");
glob.out.printf("xdc_Bool %1Module__startupDone__S( void ) \n{%+\n", glob.cname);
glob.out.printf("%treturn %1Module__startupDone__S();\n}\n%-", dcname);
if (unit.isInst()) {
glob.genTitleD("Object__create__S");
genCreateSig();
// glob.out.printf("xdc_Ptr %1Object__create__S( xdc_Ptr oa, xdc_SizeT osz, const xdc_Ptr aa, ", glob.cname);
// glob.out.printf("const %2__ParamsPtr pa, xdc_SizeT sz, %1 eb ) \n{\n%+",
// Glob.ERRBLK, glob.cname);
glob.out.printf("%treturn %1Object__create__S(oa, osz, aa, ", dcname);
glob.out.printf("(%1__ParamsPtr)pa, sizeof(%2Params), eb);\n}\n%-", dcname, icn);
glob.genTitleD("Object__delete__S");
glob.out.printf("void %1Object__delete__S( Ptr instp ) \n{\n%+", glob.cname);
glob.out.printf("%t%1Object__delete__S(instp);\n}\n%-", dcname);
glob.genTitleD("Params__init__S");
glob.out.printf("void %1Params__init__S( xdc_Ptr dst, const xdc_Ptr src, xdc_SizeT psz, xdc_SizeT isz )\n{\n%+",
glob.cname);
glob.out.printf("%t%1Params__init__S(dst, src, psz, isz);\n}\n%-", dcname);
glob.genTitleD("Handle__label__S");
String ls = "xdc_runtime_Types_Label";
glob.out.printf("%1* %2Handle__label__S( Ptr obj, %1* lab )\n{\n%+", ls, glob.cname);
glob.out.printf("%treturn %1Handle__label__S(obj, lab);\n}\n%-", dcname);
}
boolean isAbs = unit.isInst() && mod.geti("abstractInstances$") == 1;
for (Decl.Fxn fxn : unit.getFxns()) {
if (fxn.isMeta() || fxn.isSys()) {
continue;
}
String fn = fxn.getName() + ((fxn.isVarg()) ? "_va" : "") + "__E";
glob.genTitleD(fn);
fn = glob.cname + fn;
glob.genType(fxn.getType(), Glob.Type$TYP, fn);
glob.out.print("(");
String sp = " ";
if (fxn.isInst()) {
glob.out.printf(" %1Handle __inst", glob.cname);
sp = ", ";
}
glob.genArgDecls(fxn.getArgs(), Glob.Type$LCL, sp);
if (fxn.isVarg()) {
glob.out.printf(", va_list _va");
}
glob.out.printf(" )\n{\n%+%t");
if (!glob.isVoid(fxn)) {
glob.out.printf("return ");
}
sp = "";
if (!fxn.isInst()) {
glob.out.printf("%1%2(", dcname, fxn.getName());
}
else if (!isAbs) {
glob.out.printf("%1%2((%1Handle)__inst", dcname, fxn.getName());
sp = ", ";
}
else {
glob.out.printf("%1%2((%1Handle)__inst", icn, fxn.getName());
sp = ", ";
}
glob.genArgNames(fxn.getArgs(), sp);
if (fxn.isVarg()) {
glob.out.printf(", _va");
}
glob.out.printf(");\n}\n%-");
}
}
/*
* ======== genRomSect ========
*/
private void genRomSect(String cn, String dn, char code)
{
glob.out.printf("\n#ifdef __ti__\n");
glob.out.printf("%+%t#pragma DATA_SECTION(%1%2, \".modobj__%3:%1%2\");\n%-", cn, dn, code);
glob.out.printf("#endif\n\n");
}
/*
* ======== genCordAddr ========
*/
private String genCordAddr(int cid)
{
if (cid == 0 || cid >= 0x8000) {
return "0";
}
String tab = "xdc_runtime_Text_charTab__A";
return "(xdc_runtime_Text_CordAddr)(" + tab + "+" + cid + ")";
}
/*
* ======== genStruct ========
*/
private void genStruct(Value.Obj str, boolean isConst)
{
if (str.geti("$hostonly") == 1) {
return;
}
String ts = str.getProto().tname();
if (otype(ts) != STRUCT) {
return;
}
if (ts.endsWith(".Module_State") || ts.endsWith(".Instance_State")) {
return;
}
if (str.getRoot() != str && str.getRoot() instanceof Value.Obj) {
genStruct((Value.Obj)str.getRoot(), isConst);
return;
}
if (str.getPrnt() != null) {
return;
}
String is = str.getPath().substring(0, str.getPath().indexOf('/')).replace('#', '_').replace('.', '_');
String cs = ts.replace('.', '_');
if (!strset.add(is)) {
return;
}
genPreds(str, "", (ts.substring(ts.lastIndexOf('.') + 1) + "__"), isConst);
is += "__T";
if (mode == VALMODE && isConst) {
clink(is);
}
glob.genTitleD("--> " + is);
glob.out.printf("__FAR__ %3%1 %2", cs, is, isConst ? "const " : "");
if (mode == DCLMODE) {
glob.out.printf(";\n");
}
else {
glob.out.printf(" = {\n%+");
if (ts.endsWith(".Params")) {
glob.out.printf("%tsizeof (%1), /* __size */\n", cs);
glob.out.printf("%t&%1, /* __self */\n", is);
glob.out.printf("%t0, /* __fxns */\n");
glob.out.printf("%t(xdc_runtime_IInstance_Params*)&%1.__iprms, /* instance */\n", is);
}
genFlds(str);
glob.out.printf("%-};\n");
}
}
/*
* ======== genSymbols ========
*/
void genSymbols(Value prog, Out out)
{
glob.mode = Glob.CDLMODE;
glob.out = out;
Value smap = prog.getv("symbol");
Object[] keys = smap.getIds();
for (int i = 0; i < keys.length; i++) {
String errMsg = null;
String vname = (String)keys[i];
Object oval = smap.get(vname, smap);
if (oval instanceof Value.Obj) {
Value.Obj vobj = ((Value.Obj)oval).getOrig();
String tname = vobj.getProto().tname();
if (otype(tname) == INST) {
String qn = tname.substring(0, tname.lastIndexOf('.'));
String cs = qn.replace('.', '_');
String ts = cs + "_Struct";
// String ts = cs + "_Object";
glob.genInclude(glob.mkIname(qn) + "_", glob.mkFname(qn) + ".h", out);
glob.out.printf("extern %1 %2;\n", ts, vname);
}
else {
errMsg = "Program.symbol." + vname
+ " (of type " + oval.getClass().toString()
+ "): not an Instance";
}
}
else if (oval instanceof java.lang.Number) {
glob.out.printf("extern int %1;\n", vname);
}
else if (oval instanceof Ptr) {
String s = ptrToStr(oval);
//System.out.println(s);
}
else {
errMsg = "Program.symbol." + vname
+ " (of type " + oval.getClass().toString()
+ "): unsupported generation type";
}
if (errMsg != null) {
xdc.services.intern.xsr.Err.exit(errMsg);
return;
}
glob.out.printf("\n");
}
}
/*
* ======== genSysFxns ========
*/
private void genSysFxns(Value.Obj mod)
{
if (mod.geti("$$scope") == -1) {
return;
}
Unit unit = unitSpec(mod);
genTitle(mod, "SYSTEM FUNCTIONS");
/* If we generate create() function for this module, we must also
* check if we need to log LIFECYCLE events, in which case we
* need module defines used in Log_write and Diags_query.
*/
if (unit.isInst()) {
glob.genModuleDefines();
}
if (unit.isProxy()) {
// Proxy__abstract
glob.out.printf("xdc_Bool %1Proxy__abstract__S( void )\n{\n%+", glob.cname);
glob.out.printf("%treturn %1;\n}\n%-", unit.isInst() && mod.geti("abstractInstances$") == 1 ? "1" : "0");
// Proxy__delegate
glob.out.printf("xdc_Ptr %1Proxy__delegate__S( void )\n{\n%+%treturn ", glob.cname);
Value delmod = mod.getv("delegate$");
String dcname = glob.mkCname(delmod.gets("$name"));
if (commonGeti(delmod, "fxntab") == 1) {
glob.out.printf("(xdc_Ptr)&%1Module__FXNS__C;", dcname);
}
else {
glob.out.printf("0;");
}
glob.out.printf("\n}\n%-");
skip();
return;
}
// Module__startupDone
glob.genTitleD("Module__startupDone__S");
glob.out.printf("xdc_Bool %1Module__startupDone__S( void ) \n{%+\n", glob.cname);
if (!unit.attrBool(Attr.A_ModuleStartup)) {
glob.out.printf("%treturn 1;\n");
}
else {
glob.out.printf("%treturn %1Module__startupDone__F();\n", glob.cname);
}
glob.out.printf("}\n%-");
if (!unit.isInst()) {
skip();
return;
}
String cs = "xdc_runtime_Core_";
String las = "xdc_runtime_Types_Label";
String los = "xdc_runtime_Log_";
int pol = commonGeti(mod, "memoryPolicy");
// Handle__label
glob.genTitleD("Handle__label__S");
glob.out.printf("%1* %2Handle__label__S( xdc_Ptr obj, %1* lab ) \n{\n%+", las, glob.cname);
glob.out.printf("%tlab->handle = obj;\n");
glob.out.printf("%tlab->modId = %1;\n", mod.geti("Module__id"));
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%t%2assignLabel(lab, ((%1Object__*)obj)->__name, 1);\n", glob.cname, cs);
}
else {
glob.out.printf("%t%2assignLabel(lab, 0, 0);\n", glob.cname, cs);
}
glob.out.printf("\n%treturn lab;\n");
glob.out.printf("}\n%-");
// Params__init
glob.genTitleD("Params__init__S");
glob.out.printf("%2Void %1Params__init__S( %2Ptr prms, %2Ptr src, %2SizeT psz, %2SizeT isz ) \n{\n%+",
glob.cname, "xdc_");
if (pol != STATIC_POLICY) {
glob.out.printf("%t%2assignParams__I(prms, (xdc_Ptr)(src ? src : &%1Object__PARAMS__C), psz, isz);\n",
glob.cname, cs);
}
glob.out.printf("}\n%-");
// Object__get
glob.genTitleD("Object__get__S");
glob.out.printf("xdc_Ptr %1Object__get__S( xdc_Ptr oa, xdc_Int i ) \n{\n%+", glob.cname);
glob.out.printf("%tif (oa) {\n%+%treturn ((%1Object__*)oa) + i;\n%-%t}\n\n", glob.cname);
glob.out.printf("%tif (%1Object__count__C == 0) {\n%+%treturn NULL;\n%-%t}\n\n", glob.cname);
glob.out.printf("%treturn ((%1Object__*)%1Object__table__C) + i;\n", glob.cname);
glob.out.printf("}\n%-");
// Object__first
glob.genTitleD("Object__first__S");
glob.out.printf("xdc_Ptr %1Object__first__S( void ) \n{\n%+", glob.cname);
if (pol != STATIC_POLICY) {
glob.out.printf("%txdc_runtime_Types_InstHdr *iHdr = (xdc_runtime_Types_InstHdr *)%1Module__root__V.link.next;\n\n", glob.cname);
glob.out.printf("%tif (iHdr != (xdc_runtime_Types_InstHdr *)&%1Module__root__V.link) {\n%+", glob.cname);
glob.out.printf("%treturn iHdr + 1;\n");
glob.out.printf("%-%t}\n");
glob.out.printf("%telse {%+\n");
glob.out.printf("%treturn NULL;\n");
glob.out.printf("%-%t}\n");
}
else {
glob.out.printf("%treturn NULL;\n");
}
glob.out.printf("%-}\n");
// Object__next
glob.genTitleD("Object__next__S");
glob.out.printf("xdc_Ptr %1Object__next__S( xdc_Ptr obj ) \n{\n%+", glob.cname);
if (pol != STATIC_POLICY) {
glob.out.printf("%txdc_runtime_Types_InstHdr *iHdr = ((xdc_runtime_Types_InstHdr *)obj) - 1;\n\n");
glob.out.printf("%tif (iHdr->link.next != (xdc_runtime_Types_Link *)&%1Module__root__V.link) {\n%+", glob.cname);
glob.out.printf("%treturn (xdc_runtime_Types_InstHdr *)(iHdr->link.next) + 1;\n");
glob.out.printf("%-%t}\n");
glob.out.printf("%telse {%+\n");
glob.out.printf("%treturn NULL;\n");
glob.out.printf("%-%t}\n");
}
else {
glob.out.printf("%treturn NULL;\n");
}
glob.out.printf("%-}\n");
boolean iInitErr = unit.attrBool(Attr.A_InstanceInitError);
boolean iFinalize = unit.attrBool(Attr.A_InstanceFinalize);
int mask = commonGetv(mod, "logger") != null ? mod.geti("Module__diagsIncluded") : 0;
String fs = iFinalize ? ("(xdc_Fxn)" + glob.cname + "Instance_finalize__F") : "NULL";
// Object__create
glob.genTitleD("Object__create__S");
genCreateSig();
if (pol != STATIC_POLICY) {
glob.out.printf("%t%1Params prms;\n", glob.cname);
glob.out.printf("%t%1Object* obj;\n", glob.cname);
String iStat;
if (iInitErr && (pol & DELETE_POLICY) != 0) {
glob.out.printf("%tint iStat;\n", glob.cname);
iStat = "iStat = ";
}
else {
iStat = "";
}
skip();
if (unit.hasCreateArgs()) {
glob.out.printf("%t%1Args__create* args = aa;\n", glob.cname);
}
glob.out.printf("%t/* common instance initialization */\n");
glob.out.printf("%tobj = %1createObject__I(&%2Object__DESC__C, oa, osz, &prms, (xdc_Ptr)pa, psz, eb);\n",
cs, glob.cname);
glob.out.printf("%tif (obj == NULL) {\n%+%treturn NULL;\n%-%t}\n\n");
if (unit.delegatesTo() != null || unit.hasInstObj()) {
glob.out.printf("%t/* module-specific initialization */\n");
glob.out.printf("%t%2%1Instance_init__F(obj, ", glob.cname, iStat);
if (unit.hasCreateArgs()) {
for (Decl.Arg arg : unit.getCreator().getArgs()) {
glob.out.printf("args->%1, ", arg.getName());
}
}
glob.out.printf("&prms%1);\n", iInitErr ? ", eb" : "");
if (iInitErr) {
glob.out.printf("%tif (xdc_runtime_Error_check(eb)) {\n%+");
if ((pol & DELETE_POLICY) != 0) {
glob.out.printf("%t%1deleteObject__I(&%2Object__DESC__C, obj, %3, %4, (xdc_Bool)(oa != NULL));\n",
cs, glob.cname, fs, iInitErr ? "iStat" : "-1");
}
glob.out.printf("%treturn NULL;\n");
glob.out.printf("%-%t}\n\n");
}
}
if ((mask & L_LIFECYCLE) != 0) {
if (commonGeti(mod, "namedInstance") == 1) {
glob.out.printf("%t%1write2(oa ? %1L_construct : %1L_create, (xdc_IArg)obj, (xdc_IArg)(((%2Object__*)obj)->__name));\n",
los, glob.cname);
}
else {
glob.out.printf("%t%1write2(oa ? %1L_construct : %1L_create, (xdc_IArg)obj, 0);\n", los);
}
}
glob.out.printf("%treturn obj;\n");
glob.out.printf("%-}\n");
}
else {
genError(unit, "CREATE");
glob.out.printf("%treturn NULL;\n");
glob.out.printf("%-}\n");
}
if (pol == DELETE_POLICY) {
// Object__destruct
glob.genTitleD("Object__destruct__S");
glob.out.printf("xdc_Void %1Object__destruct__S( xdc_Ptr obj ) \n{\n%+", glob.cname);
if ((mask & L_LIFECYCLE) != 0) {
glob.out.printf("%t%1write1(%1L_destruct, (xdc_IArg)obj);\n", los);
}
glob.out.printf("%t%1deleteObject__I(&%2Object__DESC__C, obj, %3, %4, TRUE);\n",
cs, glob.cname, fs, iInitErr ? "0" : "-1");
glob.out.printf("%-}\n");
// Object__delete
glob.genTitleD("Object__delete__S");
glob.out.printf("xdc_Void %1Object__delete__S( xdc_Ptr instp ) \n{\n%+", glob.cname);
if ((mask & L_LIFECYCLE) != 0) {
glob.out.printf("%t%1write1(%1L_delete, (xdc_IArg)(*((%2Object**)instp)));\n", los, glob.cname);
}
glob.out.printf("%t%1deleteObject__I(&%2Object__DESC__C, *((%2Object**)instp), %3, %4, FALSE);\n",
cs, glob.cname, fs, iInitErr ? "0" : "-1");
glob.out.printf("%t*((%1Handle*)instp) = NULL;\n", glob.cname);
glob.out.printf("%-}\n");
}
else {
glob.genTitleD("Object__destruct__S");
glob.out.printf("xdc_Void %1Object__destruct__S( xdc_Ptr obj ) \n{\n%+", glob.cname);
genError(unit, "DELETE");
glob.out.printf("%-}\n");
glob.genTitleD("Object__delete__S");
glob.out.printf("xdc_Void %1Object__delete__S( xdc_Ptr instp ) \n{\n%+", glob.cname);
genError(unit, "DELETE");
glob.out.printf("%-}\n");
}
}
/*
* ======== genTemplate ========
*/
private void genTemplate(Value.Obj mod)
{
if (!(mod.has("TEMPLATE$", mod))) {
return;
}
genTitle(mod, "TEMPLATE");
String tplt = mod.gets("TEMPLATE$");
String fname = tplt.startsWith("./") ? mod.getv("$package").gets("packageBase") + tplt : tplt;
try {
progGen.genList.addAll( /* add recurs templates */
Template.exec(fname, glob.out, mod, new Object[] {fname})
);
}
catch (Exception e) {
xdc.services.intern.xsr.Err.exit(e);
}
}
/*
* ======== genTitle ========
*/
private void genTitle(Value.Obj mod, String msg)
{
glob.genTitle(mod.getName() + ' ' + msg);
}
/*
* ======== genVal ========
*/
private void genVal(Proto proto, Object oval)
{
genVal(proto, oval, null);
}
private void genVal(Proto proto, Object oval, String cast)
{
String vs = "";
if (proto instanceof Proto.Elm) {
vs = valToStr((Proto.Elm)proto, oval);
}
else if (proto instanceof Proto.Obj) {
vs = valToStr((Value.Obj)oval);
}
else if (proto instanceof Proto.Str) {
Value.Obj vobj = (Value.Obj)oval;
if (vobj.geti("$hostonly") == 1) { /// filtered in caller ???
return;
}
genAgg(vobj);
vs = "}";
}
else if (proto instanceof Proto.Arr) {
vs = valToStr((Value.Arr)oval, cast);
}
else if (proto instanceof Proto.Enm) {
vs = valToStr((xdc.services.intern.xsr.Enum)oval);
}
else if (proto instanceof Proto.Adr) {
if (cast != null) {
vs = "((" + cast + ')' + ptrToStr(oval) + ')';
}
else {
vs = "((" + ((Proto.Adr)proto).getSig() + ')' + ptrToStr(oval) + ')';
}
}
else if (proto instanceof Proto.Typedef) {
Proto.Typedef ptyp = (Proto.Typedef)proto;
if (ptyp.getEncFxn() == null) {
genVal(ptyp.getBase(), oval, cast);
return;
}
else {
Object res = null;
try {
Context cx = Context.getCurrentContext();
Scriptable scope = Global.getTopScope();
Scriptable thisObj = null;
res = ptyp.getEncFxn().call(cx, scope, thisObj, new Object[] {oval});
}
catch (Exception e) {
xdc.services.intern.xsr.Err.exit(e);
}
vs = (String)res;
}
}
glob.out.print(vs);
}
/*
* ======== val2mod ========
*/
private String val2mod( Value val )
{
Value.Obj vobj = (Value.Obj)val.getRoot();
String tn = vobj.getOrig().getProto().tname();
return tn.substring(0, tn.lastIndexOf("."));
}
/*
* ======== aname ========
*/
private String aname(Value.Arr arr)
{
String ns = arr.getPath().substring(0, arr.getPath().lastIndexOf('/')).replaceAll("[/#$.]", "_");
String suf = arr.getProto().getDim() == -1 ? "__A" : ""; // redundant ???
return ns + suf;
}
/*
* ======== clink ========
*/
private void clink(String ns)
{
clvec.add(ns);
}
/*
* ======== commonGeti ========
*/
private int commonGeti(Value mod, String name)
{
return ((Value.Obj)mod.getv("common$")).geti(name);
}
/*
* ======== commonGets ========
*/
private String commonGets(Value mod, String name)
{
return ((Value.Obj)mod.getv("common$")).gets(name);
}
/*
* ======== commonGetv ========
*/
private Value commonGetv(Value mod, String name)
{
return ((Value.Obj)mod.getv("common$")).getv(name);
}
/*
* ======== instArr ========
*/
private String instArr(String cname)
{
return cname + "Object__table__V";
}
/*
* ======== iobjKind ========
*/
private int iobjKind(Value.Obj mod)
{
if (mod.geti("PROXY$") == 1) {
return IOBJ_PROXY;
}
else if (mod.geti("$$dlgflag") == 0) {
return IOBJ_BASIC;
}
else if (mod.geti("$$sizeflag") == 1) {
return IOBJ_DLGST;
}
else {
return IOBJ_DLGPR;
}
}
/*
* ======== hasLogHdr ========
*/
private boolean hasLogHdr(Value.Obj mod)
{
return commonGetv(mod, "logger") != null &&
(mod.geti("Module__diagsIncluded") ^ mod.geti("Module__diagsEnabled")) != 0;
}
/*
* ======== isasm ========
*/
private boolean isasm(Value.Obj mod)
{
return asmset.contains(mod);
}
/*
* ======== modDeleg ========
*/
private Value.Obj modDeleg(Value.Obj mod)
{
Value vobj = mod.getv("delegate$");
return vobj == null ? mod : modDeleg(((Value.Obj)vobj).getOrig());
}
/*
* ======== otype ========
*/
private int otype(String tname)
{
return (
tname.endsWith(".Module") ? MOD :
tname.endsWith(".Instance") ? INST :
STRUCT
);
}
/*
* ======== oval ========
*/
private String oval(Proto.Elm proto, Object elm)
{
if (elm == null) {
return "0";
}
else if (elm instanceof String) {
String s = (String)elm;
if (!s.startsWith("\"")) {
s = "\"" + s + "\"";
}
return s;
}
else if (elm instanceof Number) {
String cast = (proto != null && proto.getCast() != null) ? proto.getCast() : "";
return (cast + Proto.Elm.numval((Number)elm));
}
else if (elm instanceof Boolean) {
boolean bval = ((Boolean)elm).booleanValue();
return (bval ? "1" : "0");
}
else {
return "";
}
}
/*
* ======== pkgSpec ========
*/
private Pkg pkgSpec(Value.Obj pkg)
{
Object obj = pkg.get("$spec", null);
if (obj instanceof Pkg) {
return (Pkg)obj;
}
NativeJavaObject nobj = (NativeJavaObject)obj;
return (Pkg)nobj.unwrap();
}
/*
* ======== ptrToStr ========
*/
private String ptrToStr(Object pobj) // Proto.Adr
{
if (pobj == null) {
return "0";
}
else if (pobj instanceof Extern) {
Extern ext = (Extern)pobj;
String ns = ext.isRaw() ? ext.getName() : ext.getName().replace('.', '_'); /// already has '_' ???
if (ext.isFxnT()) {
return "((xdc_Fxn)" + ns + ")";
}
else if (ext.getSig() == null || (ext.getSig().endsWith("*") || ext.getSig().equals("xdc_Ptr"))) {
return "((void*)&" + ns + ")";
}
else {
return ns;
}
}
else if (pobj instanceof Addr) {
Addr addr = (Addr)pobj;
return "((void*)0x" + Long.toHexString(addr.getVal()) + ")";
}
else if (pobj instanceof Value.Obj) {
return "((void*)" + valToStr((Value.Obj)pobj) + ")";
}
else if (pobj instanceof Ptr) {
return "((void*)" + ptrToStr((Ptr)pobj) + ")";
}
else if (pobj instanceof xdc.services.intern.xsr.Enum) {
return "((void*)(int)" + valToStr((xdc.services.intern.xsr.Enum)pobj) + ")";
}
else {
// TODO -- deal with 'Arg'
return "((void*)" + valToStr(pobj) + ")";
}
}
/*
* ======== ptrToStr ========
*/
private String ptrToStr(Ptr ptr)
{
if (ptr.getAgg() instanceof Value.Arr) {
Value.Arr arr = (Value.Arr)ptr.getAgg();
return "&" + aname(arr) + '[' + ((Number)ptr.getSel()).intValue() + ']';
}
Value.Obj vobj = ((Value.Obj)ptr.getAgg()).getOrig();
String ts = ((Proto.Obj)vobj.getProto()).tname();
int ot = otype(ts);
if (ot == MOD) {
String ns = glob.mkIname(ts.substring(0, ts.lastIndexOf('.'))) + ptr.getSel().toString() + "__C" ;
return "&" + ns;
}
if (ot == INST) {
xdc.services.intern.xsr.Err.exit("bad pointer");
return "0";
}
if (ot == STRUCT) {
return valToStr(vobj) + '.' + ptr.getSel().toString();
}
return "0";
}
/*
* ======== skip ========
*/
private void skip()
{
glob.out.print("\n");
}
/*
* ======== unitSpec ========
*/
private Unit unitSpec(Value.Obj mod)
{
Unit u;
Object obj = mod.get("$spec", null);
u = (Unit)(obj instanceof NativeJavaObject ? ((NativeJavaObject)obj).unwrap() : obj);
if (glob.curUnit != u) {
glob.curUnit = u;
glob.cname = glob.mkCname(u.getQualName());
}
return u;
}
/*
* ======== undef ========
*/
private boolean undef(Object oval)
{
return oval instanceof Undefined ||
(oval instanceof Number && Double.isNaN(((Number)oval).doubleValue()));
}
/*
* ======== valToStr ========
*/
private String valToStr(Value.Arr varr, String cast) // Proto.Arr
{
Proto.Arr parr = varr.getProto();
int len = varr.geti("length");
String as = (len == 0) ? "0" : aname(varr);
if (parr.getDim() > 0) {
genArrVals(varr, "", "");
glob.out.tab();
return "}";
}
else if (parr.getLflag()) {
if (len == 0) {
return "{0, 0}";
}
else {
String cts = varr.getCtype();
return "{" + len + ", ((" + cts + "*)" + as + ")}";
}
}
else if (cast != null) {
return "((" + cast + ')' + as + ')';
}
else {
return "((void*)" +as + ')';
}
}
private String valToStr(Object elmval) // Proto.Elm
{
return oval(null, elmval);
}
private String valToStr(Proto.Elm proto, Object elmval) // Proto.Elm
{
return oval(proto, elmval);
}
private String valToStr(xdc.services.intern.xsr.Enum enmval) // Proto.Enm
{
return enmval.getName().replace('.', '_');
}
private String valToStr(Value.Obj vobj) // Proto.Obj
{
if (vobj == null) {
return "0";
}
String tname = vobj.getProto().tname();
String otname = vobj.getOrig().getProto().tname();
int ot = otype(otname);
String cn = otname.substring(0, otname.lastIndexOf('.')).replace('.', '_');
String an = tname.replace('.', '_');
if (ot == MOD) {
return "(" + an + ")&" + cn + "_Module__FXNS__C";
}
if (ot == INST) {
Value.Obj dobj = (Value.Obj)vobj.getv("delegate$");
if (dobj != null) {
vobj = dobj;
otname = vobj.getOrig().getProto().tname();
cn = otname.substring(0, otname.lastIndexOf('.')).replace('.', '_');
}
an = tname.substring(0, tname.lastIndexOf('.')).replace('.', '_') + "_Handle";
return "(" + an + ")&" + instArr(cn + '_') + "[" + vobj.geti("$index") + "]";
}
int nxt;
if ((nxt = vobj.getPath().indexOf('/')) == -1) {
return "";
}
Stack pstk = new Stack();
for (Value v = vobj; v != null; v = v.getPrnt()) {
pstk.push(v);
}
String res = vobj.getPath().substring(0, nxt);
boolean under = true;
int k = res.indexOf("#");
if (k == -1) {
res = cn;
}
else {
String pre = res.substring(0, k);
int k2;
if ((k2 = pre.indexOf(".Instance_State")) != -1) {
cn = pre.substring(0, k2).replace('.', '_');
// an = tname.substring(0, tname.lastIndexOf('.')).replace('.', '_') + "_Handle";
res = instArr(cn + '_') + "[" + res.substring(k + 1) + "]";
// res = "(*(" + an + ")&" + res + ")";
}
else if ((k2 = pre.indexOf(".Module_State")) != -1) {
cn = pre.substring(0, k2).replace('.', '_');
/// res = cn + "__MODULE__";
res = cn + "_Module__state__V";
}
else {
res = res.replace('.', '_');
res = res.replaceFirst("#(\\d+)", "_$1__T");
}
under = false;
}
for (int cur = nxt+1; (nxt = vobj.getPath().indexOf('/', cur)) != -1; cur = nxt+1) {
Value v = (Value)pstk.pop();
String sel = vobj.getPath().substring(cur, nxt);
if (v instanceof Value.Arr) {
Value.Arr arr = (Value.Arr)v;
if (arr.getProto().getDim() > 0) {
res += "[" + sel + "]";
}
else {
res = aname((Value.Arr)v) + "[" + sel + "]";
}
continue;
}
res += (under ? '_' : '.') + (sel.equals("$delegate") ? "__deleg" : sel);
if (under && !(sel.equals("$delegate"))) {
res += "__C";
}
under = false;
}
if (tname.endsWith(".Instance")) {
an = tname.substring(0, tname.lastIndexOf('.')).replace('.', '_') + "_Handle";
return "(" + an + ")&" + res;
}
else {
return "&" + res;
}
}
}