aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/NativeFunction.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/NativeFunction.java')
-rw-r--r--src/jdk/nashorn/internal/objects/NativeFunction.java308
1 files changed, 0 insertions, 308 deletions
diff --git a/src/jdk/nashorn/internal/objects/NativeFunction.java b/src/jdk/nashorn/internal/objects/NativeFunction.java
deleted file mode 100644
index 4b8029ca..00000000
--- a/src/jdk/nashorn/internal/objects/NativeFunction.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) 2010, 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 jdk.nashorn.internal.objects;
-
-import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.Source.sourceFor;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.util.List;
-import jdk.internal.dynalink.support.Lookup;
-import jdk.nashorn.api.scripting.JSObject;
-import jdk.nashorn.internal.objects.annotations.Attribute;
-import jdk.nashorn.internal.objects.annotations.Constructor;
-import jdk.nashorn.internal.objects.annotations.Function;
-import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.parser.Parser;
-import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.ParserException;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptEnvironment;
-import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.linker.Bootstrap;
-
-/**
- * ECMA 15.3 Function Objects
- *
- * Note: instances of this class are never created. This class is not even a
- * subclass of ScriptObject. But, we use this class to generate prototype and
- * constructor for "Function".
- */
-@ScriptClass("Function")
-public final class NativeFunction {
-
- /** apply arg converter handle */
- public static final MethodHandle TO_APPLY_ARGS = Lookup.findOwnStatic(MethodHandles.lookup(), "toApplyArgs", Object[].class, Object.class);
-
- // initialized by nasgen
- @SuppressWarnings("unused")
- private static PropertyMap $nasgenmap$;
-
- // do *not* create me!
- private NativeFunction() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * ECMA 15.3.4.2 Function.prototype.toString ( )
- *
- * @param self self reference
- * @return string representation of Function
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toString(final Object self) {
- if (!(self instanceof ScriptFunction)) {
- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
- }
- return ((ScriptFunction)self).toSource();
- }
-
- /**
- * ECMA 15.3.4.3 Function.prototype.apply (thisArg, argArray)
- *
- * @param self self reference
- * @param thiz {@code this} arg for apply
- * @param array array of argument for apply
- * @return result of apply
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static Object apply(final Object self, final Object thiz, final Object array) {
- checkCallable(self);
-
- final Object[] args = toApplyArgs(array);
-
- if (self instanceof ScriptFunction) {
- return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
- } else if (self instanceof JSObject) {
- return ((JSObject)self).call(thiz, args);
- }
- throw new AssertionError("Should not reach here");
- }
-
- /**
- * Given an array-like object, converts it into a Java object array suitable for invocation of ScriptRuntime.apply
- * or for direct invocation of the applied function.
- * @param array the array-like object. Can be null in which case a zero-length array is created.
- * @return the Java array
- */
- public static Object[] toApplyArgs(final Object array) {
- if (array instanceof NativeArguments) {
- return ((NativeArguments)array).getArray().asObjectArray();
- } else if (array instanceof ScriptObject) {
- // look for array-like object
- final ScriptObject sobj = (ScriptObject)array;
- final int n = lengthToInt(sobj.getLength());
-
- final Object[] args = new Object[n];
- for (int i = 0; i < args.length; i++) {
- args[i] = sobj.get(i);
- }
- return args;
- } else if (array instanceof Object[]) {
- return (Object[])array;
- } else if (array instanceof List) {
- final List<?> list = (List<?>)array;
- return list.toArray(new Object[list.size()]);
- } else if (array == null || array == UNDEFINED) {
- return ScriptRuntime.EMPTY_ARRAY;
- } else if (array instanceof JSObject) {
- // look for array-like JSObject object
- final JSObject jsObj = (JSObject)array;
- final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0);
- final int n = lengthToInt(len);
-
- final Object[] args = new Object[n];
- for (int i = 0; i < args.length; i++) {
- args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED;
- }
- return args;
- } else {
- throw typeError("function.apply.expects.array");
- }
- }
-
- private static int lengthToInt(final Object len) {
- final long ln = JSType.toUint32(len);
- // NOTE: ECMASCript 5.1 section 15.3.4.3 says length should be treated as Uint32, but we wouldn't be able to
- // allocate a Java array of more than MAX_VALUE elements anyway, so at this point we have to throw an error.
- // People applying a function to more than 2^31 arguments will unfortunately be out of luck.
- if (ln > Integer.MAX_VALUE) {
- throw rangeError("range.error.inappropriate.array.length", JSType.toString(len));
- }
- return (int)ln;
- }
-
- private static void checkCallable(final Object self) {
- if (!(self instanceof ScriptFunction || (self instanceof JSObject && ((JSObject)self).isFunction()))) {
- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
- }
- }
-
- /**
- * ECMA 15.3.4.4 Function.prototype.call (thisArg [ , arg1 [ , arg2, ... ] ] )
- *
- * @param self self reference
- * @param args arguments for call
- * @return result of call
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
- public static Object call(final Object self, final Object... args) {
- checkCallable(self);
-
- final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
- Object[] arguments;
-
- if (args.length > 1) {
- arguments = new Object[args.length - 1];
- System.arraycopy(args, 1, arguments, 0, arguments.length);
- } else {
- arguments = ScriptRuntime.EMPTY_ARRAY;
- }
-
- if (self instanceof ScriptFunction) {
- return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments);
- } else if (self instanceof JSObject) {
- return ((JSObject)self).call(thiz, arguments);
- }
-
- throw new AssertionError("should not reach here");
- }
-
- /**
- * ECMA 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
- *
- * @param self self reference
- * @param args arguments for bind
- * @return function with bound arguments
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
- public static Object bind(final Object self, final Object... args) {
- final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
-
- Object[] arguments;
- if (args.length > 1) {
- arguments = new Object[args.length - 1];
- System.arraycopy(args, 1, arguments, 0, arguments.length);
- } else {
- arguments = ScriptRuntime.EMPTY_ARRAY;
- }
-
- return Bootstrap.bindCallable(self, thiz, arguments);
- }
-
- /**
- * Nashorn extension: Function.prototype.toSource
- *
- * @param self self reference
- * @return source for function
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toSource(final Object self) {
- if (!(self instanceof ScriptFunction)) {
- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
- }
- return ((ScriptFunction)self).toSource();
- }
-
- /**
- * ECMA 15.3.2.1 new Function (p1, p2, ... , pn, body)
- *
- * Constructor
- *
- * @param newObj is the new operator used for constructing this function
- * @param self self reference
- * @param args arguments
- * @return new NativeFunction
- */
- @Constructor(arity = 1)
- public static ScriptFunction function(final boolean newObj, final Object self, final Object... args) {
- final StringBuilder sb = new StringBuilder();
-
- sb.append("(function (");
- final String funcBody;
- if (args.length > 0) {
- final StringBuilder paramListBuf = new StringBuilder();
- for (int i = 0; i < args.length - 1; i++) {
- paramListBuf.append(JSType.toString(args[i]));
- if (i < args.length - 2) {
- paramListBuf.append(",");
- }
- }
-
- // now convert function body to a string
- funcBody = JSType.toString(args[args.length - 1]);
-
- final String paramList = paramListBuf.toString();
- if (!paramList.isEmpty()) {
- checkFunctionParameters(paramList);
- sb.append(paramList);
- }
- } else {
- funcBody = null;
- }
-
- sb.append(") {\n");
- if (args.length > 0) {
- checkFunctionBody(funcBody);
- sb.append(funcBody);
- sb.append('\n');
- }
- sb.append("})");
-
- final Global global = Global.instance();
- final Context context = global.getContext();
- return (ScriptFunction)context.eval(global, sb.toString(), global, "<function>");
- }
-
- private static void checkFunctionParameters(final String params) {
- final Parser parser = getParser(params);
- try {
- parser.parseFormalParameterList();
- } catch (final ParserException pe) {
- pe.throwAsEcmaException();
- }
- }
-
- private static void checkFunctionBody(final String funcBody) {
- final Parser parser = getParser(funcBody);
- try {
- parser.parseFunctionBody();
- } catch (final ParserException pe) {
- pe.throwAsEcmaException();
- }
- }
-
- private static Parser getParser(final String sourceText) {
- final ScriptEnvironment env = Global.getEnv();
- return new Parser(env, sourceFor("<function>", sourceText), new Context.ThrowErrorManager(), env._strict, null);
- }
-}