--- /dev/null 2016-09-01 15:38:59.076007815 -0400 +++ new/modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/model/SymbolTable.java 2016-09-11 10:36:03.408826263 -0400 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.scenario.effect.compiler.model; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + */ +public class SymbolTable { + + private final Map globalVariableMap = new HashMap(); + private final Map localVariableMap = new HashMap(); + private final Set globalFunctionSet = new HashSet(); + private int numSamplers; + private int numParams; + private boolean global = true; + + public SymbolTable() { + declareCoreFunctions(); + } + + private Variable declareParamVariable(String name, Type type) { + return declareVariable(name, type, null, null, -1, null, true); + } + + public Variable declareVariable(String name, Type type, + Qualifier qual) + { + return declareVariable(name, type, qual, null); + } + + public Variable declareVariable(String name, Type type, + Qualifier qual, Precision precision) + { + return declareVariable(name, type, qual, precision, -1, null, false); + } + + public Variable declareVariable(String name, Type type, + Qualifier qual, Precision precision, + int arraySize, Object constValue) + { + return declareVariable(name, type, qual, precision, + arraySize, constValue, false); + } + + public Variable declareVariable(String name, Type type, + Qualifier qual, Precision precision, + int arraySize, Object constValue, + boolean isParam) + { + Map vars = getVariablesForScope(); + Variable v = vars.get(name); + if (v != null) { + throw new RuntimeException("Variable '" + name + "' already declared"); + } + + if (arraySize == 0) { + throw new RuntimeException("Array size cannot be zero"); + } + + int reg = -1; + if (qual == Qualifier.PARAM) { + if (!global) { + throw new RuntimeException("Param variable can only be declared in global scope"); + } + if (type.getBaseType() == BaseType.SAMPLER) { + reg = numSamplers; + numSamplers++; + } else { + reg = numParams; + if (arraySize > 0) { + numParams += arraySize; + } else { + numParams++; + } + } + } + + v = new Variable(name, type, qual, precision, + reg, arraySize, constValue, isParam); + vars.put(name, v); + return v; + } + + public Function declareFunction(String name, Type returnType, List params) { + Function f = new Function(name, returnType, params); + if (isFunctionDeclared(f)) { + throw new RuntimeException("Function '" + name + "' already declared"); + } + if (name.equals("main") && (params == null || params.isEmpty())) { + if (localVariableMap.isEmpty()) { + // core variables are implicitly declared for main() only + for (Variable v : CoreSymbols.getAllVariables()) { + localVariableMap.put(v.getName(), v); + } + } + } + if (params != null) { + // only declare parameters for non-core functions so that they + // are visible in the function's scope (we skip this step for + // core functions because the way the code is currently set up, + // we'd end up declaring core function parameters in global scope; + // we should clean this up later) + for (Param param : params) { + declareParamVariable(param.getName(), param.getType()); + } + } + declareUserFunction(f); + return f; + } + + public void enterFrame() { + global = false; + localVariableMap.clear(); + } + + public void exitFrame() { + global = true; + } + + private void declareCoreFunctions() { + globalFunctionSet.addAll(CoreSymbols.getAllFunctions()); + } + + public Map getGlobalVariables() { + return globalVariableMap; + } + + private boolean isFunctionDeclared(Function func) { + return globalFunctionSet.contains(func); + } + + private void declareUserFunction(Function func) { + globalFunctionSet.add(func); + } + + public Function getFunctionForSignature(String name, List ptypes) { + return getFunctionForSignature(globalFunctionSet, name, ptypes); + } + + static Function getFunctionForSignature(Set funcs, + String name, + List ptypes) + { + for (Function f : funcs) { + List params = f.getParams(); + if (name.equals(f.getName()) && params.size() == ptypes.size()) { + boolean match = true; + for (int i = 0; i < params.size(); i++) { + if (params.get(i).getType() != ptypes.get(i)) { + match = false; + break; + } + } + if (match) { + return f; + } + } + } + return null; + } + + public Map getVariablesForScope() { + if (global) { + return globalVariableMap; + } else { + return localVariableMap; + } + } + + public int getNumSamplers() { + return numSamplers; + } +}