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.objects; 27 28 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 29 import static jdk.nashorn.internal.runtime.linker.Lookup.MH; 30 31 import java.lang.invoke.MethodHandle; 32 import java.lang.invoke.MethodHandles; 33 import jdk.nashorn.internal.codegen.objects.FunctionObjectCreator; 34 import jdk.nashorn.internal.runtime.GlobalFunctions; 35 import jdk.nashorn.internal.runtime.Property; 36 import jdk.nashorn.internal.runtime.PropertyMap; 37 import jdk.nashorn.internal.runtime.ScriptFunction; 38 import jdk.nashorn.internal.runtime.ScriptObject; 39 import jdk.nashorn.internal.runtime.ScriptRuntime; 40 import jdk.nashorn.internal.runtime.Source; 41 import jdk.nashorn.internal.runtime.linker.Lookup; 42 import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; 43 44 /** 45 * Concrete implementation of ScriptFunction. This sets correct map for the 46 * function objects -- to expose properties like "prototype", "length" etc. 47 */ 48 public class ScriptFunctionImpl extends ScriptFunction { 49 // per-function object flags 50 private static final int IS_STRICT = 0b0000_0001; 51 private static final int IS_BUILTIN = 0b0000_0010; 52 private static final int HAS_CALLEE = 0b0000_0100; 77 * @param name name of function 78 * @param invokeHandle handle for invocation 79 * @param specs specialized versions of this method, if available, null otherwise 80 */ 81 ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) { 82 this(name, invokeHandle, nasgenmap$, specs); 83 } 84 85 /** 86 * Constructor 87 * 88 * Called by Nasgen generated code, no membercount, use the default map 89 * Creates builtin functions only 90 * 91 * @param name name of function 92 * @param methodHandle handle for invocation 93 * @param map initial property map 94 * @param specs specialized versions of this method, if available, null otherwise 95 */ 96 ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final PropertyMap map, final MethodHandle[] specs) { 97 super(name, methodHandle, (nasgenmap$ == map) ? nasgenmap$ : map.addAll(nasgenmap$), null, null, 0, false, specs); 98 this.setIsBuiltin(); 99 init(); 100 } 101 102 /** 103 * Constructor 104 * 105 * Called by Global.newScriptFunction (runtime) 106 * 107 * @param name name of function 108 * @param methodHandle handle for invocation 109 * @param scope scope object 110 * @param strict are we in strict mode 111 * @param specs specialized versions of this method, if available, null otherwise 112 */ 113 ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final boolean strict, final MethodHandle[] specs) { 114 super(name, methodHandle, getMap(strict), scope, specs); 115 if (strict) { 116 this.setIsStrict(); 117 } 118 init(); 119 } 120 121 /** 122 * Constructor 123 * 124 * Called by (compiler) generated code for {@link ScriptObject}s. Code is 125 * generated by {@link FunctionObjectCreator} 126 * 127 * TODO this is a horrible constructor - can we do it with fewer args? 128 * 129 * @param name name of function 130 * @param methodHandle handle for invocation 131 * @param scope scope object 132 * @param source source 133 * @param token token 134 * @param allocator instance constructor for function 135 * @param allocatorMap initial map that constructor will keep reference to for future instantiations 136 * @param needCallee does the function use the {@code callee} variable 137 * @param strict are we in strict mode 138 */ 139 public ScriptFunctionImpl( 140 final String name, 141 final MethodHandle methodHandle, 142 final ScriptObject scope, 143 final Source source, 144 final long token, 145 final MethodHandle allocator, 146 final PropertyMap allocatorMap, 147 final boolean needCallee, 148 final boolean strict) { 149 super(name, methodHandle, getMap(strict), scope, source, token, allocator, allocatorMap, needCallee, null); 150 if (strict) { 151 this.setIsStrict(); 152 } 153 init(); 154 } 155 156 static { 157 PropertyMap map = PropertyMap.newMap(ScriptFunctionImpl.class); 158 map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE); 159 map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null); 160 map = Lookup.newProperty(map, "name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null); 161 nasgenmap$ = map; 162 } 163 164 // function object representing TypeErrorThrower 165 private static ScriptFunction typeErrorThrower; 166 167 static synchronized ScriptFunction getTypeErrorThrower() { 168 if (typeErrorThrower == null) { 169 //name handle 170 final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, false, null); 171 // clear constructor handle... 172 func.constructHandle = null; 173 func.prototype = UNDEFINED; 174 typeErrorThrower = func; 175 } 176 177 return typeErrorThrower; 178 } 179 180 // add a new property that throws TypeError on get as well as set 181 static synchronized PropertyMap newThrowerProperty(final PropertyMap map, final String name, final int flags) { 182 return map.newProperty(name, flags, Lookup.TYPE_ERROR_THROWER_GETTER, Lookup.TYPE_ERROR_THROWER_SETTER); 183 } 184 185 // property map for strict mode functions - lazily initialized 186 private static PropertyMap strictmodemap$; 187 188 // Choose the map based on strict mode! 189 private static PropertyMap getMap(final boolean strict) { 190 if (strict) { 191 synchronized (ScriptFunctionImpl.class) { 192 if (strictmodemap$ == null) { | 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.objects; 27 28 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 29 import static jdk.nashorn.internal.runtime.linker.Lookup.MH; 30 31 import java.lang.invoke.MethodHandle; 32 import java.lang.invoke.MethodHandles; 33 34 import jdk.nashorn.internal.codegen.ScriptFunctionData; 35 import jdk.nashorn.internal.codegen.objects.FunctionObjectCreator; 36 import jdk.nashorn.internal.runtime.GlobalFunctions; 37 import jdk.nashorn.internal.runtime.Property; 38 import jdk.nashorn.internal.runtime.PropertyMap; 39 import jdk.nashorn.internal.runtime.ScriptFunction; 40 import jdk.nashorn.internal.runtime.ScriptObject; 41 import jdk.nashorn.internal.runtime.ScriptRuntime; 42 import jdk.nashorn.internal.runtime.Source; 43 import jdk.nashorn.internal.runtime.linker.Lookup; 44 import jdk.nashorn.internal.runtime.linker.MethodHandleFactory; 45 46 /** 47 * Concrete implementation of ScriptFunction. This sets correct map for the 48 * function objects -- to expose properties like "prototype", "length" etc. 49 */ 50 public class ScriptFunctionImpl extends ScriptFunction { 51 // per-function object flags 52 private static final int IS_STRICT = 0b0000_0001; 53 private static final int IS_BUILTIN = 0b0000_0010; 54 private static final int HAS_CALLEE = 0b0000_0100; 79 * @param name name of function 80 * @param invokeHandle handle for invocation 81 * @param specs specialized versions of this method, if available, null otherwise 82 */ 83 ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) { 84 this(name, invokeHandle, nasgenmap$, specs); 85 } 86 87 /** 88 * Constructor 89 * 90 * Called by Nasgen generated code, no membercount, use the default map 91 * Creates builtin functions only 92 * 93 * @param name name of function 94 * @param methodHandle handle for invocation 95 * @param map initial property map 96 * @param specs specialized versions of this method, if available, null otherwise 97 */ 98 ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final PropertyMap map, final MethodHandle[] specs) { 99 super(name, methodHandle, (nasgenmap$ == map) ? nasgenmap$ : map.addAll(nasgenmap$), null, false, specs); 100 this.setIsBuiltin(); 101 init(); 102 } 103 104 /** 105 * Constructor 106 * 107 * Called by Global.newScriptFunction (runtime) 108 * 109 * @param name name of function 110 * @param methodHandle handle for invocation 111 * @param scope scope object 112 * @param strict are we in strict mode 113 * @param specs specialized versions of this method, if available, null otherwise 114 */ 115 ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final boolean strict, final MethodHandle[] specs) { 116 super(name, methodHandle, getMap(strict), scope, specs); 117 if (strict) { 118 this.setIsStrict(); 119 } 120 init(); 121 } 122 123 /** 124 * Constructor 125 * 126 * Called by (compiler) generated code for {@link ScriptObject}s. Code is 127 * generated by {@link FunctionObjectCreator} 128 * 129 * @param data static function data 130 * @param methodHandle handle for invocation 131 * @param scope scope object 132 * @param allocator instance constructor for function 133 */ 134 public ScriptFunctionImpl(final ScriptFunctionData data, final MethodHandle methodHandle, 135 final ScriptObject scope, final MethodHandle allocator) { 136 super(data, methodHandle, getMap(data.isStrict()), scope, allocator); 137 if (data.isStrict()) { 138 this.setIsStrict(); 139 } 140 init(); 141 } 142 143 static { 144 PropertyMap map = PropertyMap.newMap(ScriptFunctionImpl.class); 145 map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE); 146 map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null); 147 map = Lookup.newProperty(map, "name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null); 148 nasgenmap$ = map; 149 } 150 151 // function object representing TypeErrorThrower 152 private static ScriptFunction typeErrorThrower; 153 154 static synchronized ScriptFunction getTypeErrorThrower() { 155 if (typeErrorThrower == null) { 156 //name handle 157 final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, false, null); 158 // clear constructor handle... 159 func.constructor = null; 160 func.prototype = UNDEFINED; 161 typeErrorThrower = func; 162 } 163 164 return typeErrorThrower; 165 } 166 167 // add a new property that throws TypeError on get as well as set 168 static synchronized PropertyMap newThrowerProperty(final PropertyMap map, final String name, final int flags) { 169 return map.newProperty(name, flags, Lookup.TYPE_ERROR_THROWER_GETTER, Lookup.TYPE_ERROR_THROWER_SETTER); 170 } 171 172 // property map for strict mode functions - lazily initialized 173 private static PropertyMap strictmodemap$; 174 175 // Choose the map based on strict mode! 176 private static PropertyMap getMap(final boolean strict) { 177 if (strict) { 178 synchronized (ScriptFunctionImpl.class) { 179 if (strictmodemap$ == null) { |