blob: d168431277c921f130735fb2f2bacc1e100510c8 [file] [log] [blame]
/* --COPYRIGHT--,ESD
* Copyright (c) 2008-2019 Texas Instruments Incorporated
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License
* v. 1.0 which accompanies this distribution. The Eclipse Public License is
* available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
* Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Texas Instruments - initial implementation
* --/COPYRIGHT--*/
/*
* ======== Text.xs ========
*/
var cordMap = {};
var nameMap = {};
var maxDepth = 1;
/*
* ======== module$use ========
*/
function module$use()
{
/* we don't call xdc.useModule('xdc.runtime.Registry') here anymore.
* See the comment in Text_putMod().
*/
}
/*
* ======== module$static$init ========
*/
function module$static$init(obj)
{
obj.charBase = this.charTab.$addrof(0);
obj.nodeBase = this.nodeTab.$addrof(0);
this.genModNames();
}
/*
* ======== module$view$init ========
*
* ROV code
*/
function module$view$init(view, obj)
{
view.charBase = obj.charBase;
view.charBase = obj.nodeBase;
var cfg = Program.getModuleConfig('xdc.runtime.Text');
this.$private.charBase = obj.charBase;
this.$private.charLast = $addr(obj.charBase + cfg.charCnt);
this.$private.nodeBase = obj.nodeBase;
this.$private.nodeLast = $addr(obj.nodeBase
+ (cfg.nodeCnt * this.Node.$sizeof()));
}
/*
* ======== defineRopeCord ========
* Put text in charTab[] and put its offset (within charTab) into
* cordMap[text].
*/
function defineRopeCord(text)
{
if (!text || !this.isLoaded) {
/* callers outside of this module are Assert, Error and Log, and they
* all assume that 0 means there is no name. The functions __initObject
* also call this function and assign the return value to inst.__name.
*/
return (0);
}
var cid;
if ((cid = cordMap[text]) === undefined) {
cid = cordMap[text] = this.charTab.length;
for (var i = 0; i < text.length; i++) {
this.charTab.$add(text.charCodeAt(i));
}
this.charTab.$add(0);
this.charCnt = this.charTab.length;
}
return (cid);
}
/*
* ======== defineRopeNode ========
* Create a new node and return its node id
*
* Node ids are defined as (index into nodeTab[] | 0x8000). The upper bit
* (0x8000) is set to distinguish node ids from offsets into charTab; a rope
* id is either a node id or an offset into charTab. The upper bit also
* allows us to use these IDs as module ids; unnamed modules are simply
* numbered from 1 to 0x7fff whereas named modules have ids equal to their
* "rope node id".
*
* We don't need to check 'isLoaded' here because this function is invoked
* only from genPkgName and genModNames, and the check for 'isLoaded' in
* genModNames ensures that genPkgName and defineRopeNode are not invoked if
* 'isLoaded' is false.
*/
/* REQ_TAG(SYSBIOS-892) */
function defineRopeNode(left, right)
{
var nid = this.nodeTab.length | 0x8000;
this.nodeTab.$add({left: left, right: right});
this.nodeCnt++;
return (nid);
}
/*
* ======== fetchAddr ========
* ROV invokes this function only when fetching the name of a dynamic instance.
* Names of static instances are found in the ROV capsule.
* Only when a dynamic instance gets a name that is already in the arrays
* managed by Text, the first two if-clauses will be executed.
*/
function fetchAddr(raddr)
{
var priv = this.$private;
if (raddr >= priv.charBase && raddr < priv.charLast) {
return (this.fetchCord(raddr - priv.charBase));
}
else if (raddr >= priv.nodeBase && raddr < priv.nodeLast) {
return (this.fetchNode((raddr - priv.nodeBase) / this.Node.$sizeof()));
}
else {
return (Program.fetchString(raddr, true));
}
}
/*
* ======== fetchCord ========
*
* ROV code
*/
function fetchCord(cid)
{
var cfg = Program.getModuleConfig('xdc.runtime.Text');
var res = "";
for (var i = cid; cfg.charTab[i]; res +=
String.fromCharCode(cfg.charTab[i++]));
return (res);
}
/*
* ======== fetchId ========
*
* ROV code
*/
function fetchId(rid)
{
var cfg = Program.getModuleConfig('xdc.runtime.Text');
return (
(rid & 0x8000) ? this.fetchNode(rid & ~0x8000) : this.fetchCord(rid)
);
}
/*
* ======== fetchNode ========
*
* ROV code
*/
function fetchNode(nid)
{
var cfg = Program.getModuleConfig('xdc.runtime.Text');
var node = cfg.nodeTab[nid];
return (this.fetchId(node.left) + this.fetchId(node.right));
}
/*
* ======== genModNames ========
* This function generates module IDs by "registering" module names in
* nodeTab[] and using the returned node ID or by simply incrementing a
* counter starting from one. Node IDs are guaranteed to be 0x8000
* or above, so named modules occupy 0x8000-0xFFFF. The range from 0x0001 to
* 0x7FFF is divided between unnamed modules and Registry modules.
* The module IDs are allocated as follows:
*
* 0x0000 - invalid module ID
* 0x0001 - first unnamed module ID
* :
* 0x4000 - last unnamed module ID
* 0x4001 - first Registry module ID
* :
* 0x7FFF - last Registry module ID
* 0x8000 - first named module ID
* :
* 0xFFFF - last named module ID
*
* Named modules have their string names encoded and stored on the target.
* Unnamed modules can only be identified by name via the id<->name map
* that is generated during configuration (*.rta.xml).
*/
function genModNames()
{
var idx = 1;
var Defaults = xdc.module('xdc.runtime.Defaults');
for each (var mod in Program.targetModules()) {
var mid;
if (this.isLoaded && !mod.PROXY$
&& Defaults.getCommon(mod, "namedModule") != false) {
var k = mod.$name.lastIndexOf('.');
var d = mod.$package.$name.split('.').length;
if (d > maxDepth) {
maxDepth = d;
}
mod.Module__id = this.defineRopeNode(
this.genPkgName(mod.$package.$name),
this.defineRopeCord(mod.$name.substring(k + 1))
);
}
/*
* If this is not a named module, assign it a number starting at 1.
* Named modules start at 0x8000.
*/
else {
/* Verify we haven't run out of unnamed module ids. */
if (idx > this.unnamedModsLastId) {
this.$logFatal("Too many unnamed modules.", this);
}
mod.Module__id = idx++;
}
}
// this.unnamedModCnt = idx - 1;
}
/*
* ======== genPkgName ========
*/
function genPkgName(qn)
{
var k = qn.lastIndexOf('.');
if (k == -1) {
return (this.defineRopeCord(qn + '.'));
}
var nid = nameMap[qn];
if (nid !== undefined) {
return (nid);
}
nid = this.defineRopeNode(
this.genPkgName(qn.substring(0, k)),
this.defineRopeCord(qn.substring(k + 1) + '.'));
nameMap[qn] = nid;
return (nid);
}
/*
* ======== validate ========
* This function is called during the validation phase of configuration
*/
/* REQ_TAG(SYSBIOS-887) */
function validate()
{
if (this.charCnt > 0x7FFF) {
this.$logError("The strings managed by 'Text' exceed 32K in size",
this, "charTab");
}
}