| /* --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"); |
| } |
| } |