1 /* 2 * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.runtime; 27 28 import java.io.IOException; 29 import java.io.ObjectInputStream; 30 import java.io.ObjectOutputStream; 31 import java.io.Serializable; 32 import java.lang.invoke.MethodType; 33 import java.util.Map; 34 import jdk.nashorn.internal.codegen.CompileUnit; 35 import jdk.nashorn.internal.codegen.FunctionSignature; 36 import jdk.nashorn.internal.codegen.types.Type; 37 import jdk.nashorn.internal.ir.FunctionNode; 38 39 /** 40 * Class that contains information allowing us to look up a method handle implementing a JavaScript function 41 * from a generated class. This is used both for code coming from codegen and for persistent serialized code. 42 */ 43 public final class FunctionInitializer implements Serializable { 44 45 private final String className; 46 private final MethodType methodType; 47 private final int flags; 48 private transient Map<Integer, Type> invalidatedProgramPoints; 49 private transient Class<?> code; 50 51 private static final long serialVersionUID = -5420835725902966692L; 52 53 /** 54 * Constructor. 55 * 56 * @param functionNode the function node 57 */ 58 public FunctionInitializer(final FunctionNode functionNode) { 59 this(functionNode, null); 60 } 61 62 /** 63 * Constructor. 64 * 65 * @param functionNode the function node 66 * @param invalidatedProgramPoints invalidated program points 67 */ 68 public FunctionInitializer(final FunctionNode functionNode, final Map<Integer, Type> invalidatedProgramPoints) { 69 this.className = functionNode.getCompileUnit().getUnitClassName(); 70 this.methodType = new FunctionSignature(functionNode).getMethodType(); 71 this.flags = functionNode.getFlags(); 72 this.invalidatedProgramPoints = invalidatedProgramPoints; 73 74 final CompileUnit cu = functionNode.getCompileUnit(); 75 if (cu != null) { 76 this.code = cu.getCode(); 77 } 78 79 assert className != null; 80 } 81 82 /** 83 * Returns the name of the class implementing the function. 84 * 85 * @return the class name 86 */ 87 public String getClassName() { 88 return className; 89 } 90 91 /** 92 * Returns the type of the method implementing the function. 93 * 94 * @return the method type 95 */ 96 public MethodType getMethodType() { 97 return methodType; 98 } 99 100 /** 101 * Returns the function flags. 102 * 103 * @return function flags 104 */ 105 public int getFlags() { 106 return flags; 107 } 108 109 /** 110 * Returns the class implementing the function. 111 * 112 * @return the class 113 */ 114 public Class<?> getCode() { 115 return code; 116 } 117 118 /** 119 * Set the class implementing the function 120 * @param code the class 121 */ 122 void setCode(final Class<?> code) { 123 // Make sure code has not been set and has expected class name 124 if (this.code != null) { 125 throw new IllegalStateException("code already set"); 126 } 127 assert className.equals(code.getTypeName().replace('.', '/')) : "unexpected class name"; 128 this.code = code; 129 } 130 131 /** 132 * Returns the map of invalidated program points. 133 * 134 * @return invalidated program points 135 */ 136 public Map<Integer, Type> getInvalidatedProgramPoints() { 137 return invalidatedProgramPoints; 138 } 139 140 private void writeObject(final ObjectOutputStream out) throws IOException { 141 out.defaultWriteObject(); 142 Type.writeTypeMap(invalidatedProgramPoints, out); 143 } 144 145 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { 146 in.defaultReadObject(); 147 invalidatedProgramPoints = Type.readTypeMap(in); 148 } 149 }