1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { 17 VReg 18} from "../irnodes"; 19import { PandaGen } from "../pandagen"; 20import { 21 expandFalse, 22 expandGlobal, 23 expandHole, 24 expandInfinity, 25 expandNaN, 26 expandNull, 27 expandSymbol, 28 expandTrue, 29 expandUndefined, 30 expandFunc 31} from "./builtIn"; 32import { expandLexEnv } from "./lexEnv"; 33 34 35export enum CacheList { 36 MIN, 37 NAN = MIN, 38 HOLE, 39 FUNC, // load function 40 INFINITY, 41 UNDEFINED, 42 SYMBOL, 43 NULL, 44 GLOBAL, 45 LEXENV, 46 TRUE, 47 FALSE, 48 MAX 49} 50let cacheExpandHandlers = new Map([ 51 [CacheList.HOLE, expandHole], 52 [CacheList.NAN, expandNaN], 53 [CacheList.INFINITY, expandInfinity], 54 [CacheList.UNDEFINED, expandUndefined], 55 [CacheList.SYMBOL, expandSymbol], 56 [CacheList.NULL, expandNull], 57 [CacheList.GLOBAL, expandGlobal], 58 [CacheList.LEXENV, expandLexEnv], 59 [CacheList.TRUE, expandTrue], 60 [CacheList.FALSE, expandFalse], 61 [CacheList.FUNC, expandFunc], 62]); 63 64class CacheItem { 65 constructor(handler: Function) { 66 this.flag = false; 67 this.vreg = undefined; 68 this.expander = handler; 69 } 70 private flag: boolean; 71 private vreg: VReg | undefined; 72 private expander: Function; 73 isNeeded(): boolean { 74 return this.flag; 75 } 76 getCache(): VReg { 77 if (!this.flag || !this.vreg) { 78 this.flag = true; 79 this.vreg = new VReg(); 80 } 81 return this.vreg; 82 } 83 getExpander(): Function { 84 return this.expander; 85 } 86} 87 88export class VregisterCache { 89 private cache: CacheItem[] = []; 90 constructor() { 91 for (let i = CacheList.MIN; i < CacheList.MAX; ++i) { 92 let handler = cacheExpandHandlers.get(i); 93 if (!handler) { 94 throw new Error("invalid expand handler"); 95 } 96 this.cache[i] = new CacheItem(handler); 97 } 98 } 99 getCache(index: CacheList): CacheItem { 100 if (index < CacheList.MIN || index > CacheList.MAX) { 101 throw new Error("invalid builtin index"); 102 } 103 return this.cache[index]; 104 } 105} 106 107export function getVregisterCache(pandaGen: PandaGen, index: CacheList): VReg { 108 let cache = pandaGen.getVregisterCache(); 109 let cacheItem = cache.getCache(index); 110 111 return cacheItem.getCache(); 112}