53 // "byte arity" field can be widened. 54 assert MAX_ARITY < 256; 55 } 56 57 /** Name of the function or "" for anonymous functions */ 58 protected final String name; 59 60 /** 61 * A list of code versions of a function sorted in ascending order of generic descriptors. 62 */ 63 protected transient LinkedList<CompiledFunction> code = new LinkedList<>(); 64 65 /** Function flags */ 66 protected int flags; 67 68 // Parameter arity of the function, corresponding to "f.length". E.g. "function f(a, b, c) { ... }" arity is 3, and 69 // some built-in ECMAScript functions have their arity declared by the specification. Note that regardless of this 70 // value, the function might still be capable of receiving variable number of arguments, see isVariableArity. 71 private int arity; 72 73 /** 74 * A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by 75 * multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are 76 * idempotent. 77 */ 78 private volatile transient GenericInvokers genericInvokers; 79 80 private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class); 81 82 /** Is this a strict mode function? */ 83 public static final int IS_STRICT = 1 << 0; 84 /** Is this a built-in function? */ 85 public static final int IS_BUILTIN = 1 << 1; 86 /** Is this a constructor function? */ 87 public static final int IS_CONSTRUCTOR = 1 << 2; 88 /** Does this function expect a callee argument? */ 89 public static final int NEEDS_CALLEE = 1 << 3; 90 /** Does this function make use of the this-object argument? */ 91 public static final int USES_THIS = 1 << 4; 92 /** Is this a variable arity function? */ 101 102 private static final long serialVersionUID = 4252901245508769114L; 103 104 /** 105 * Constructor 106 * 107 * @param name script function name 108 * @param arity arity 109 * @param flags the function flags 110 */ 111 ScriptFunctionData(final String name, final int arity, final int flags) { 112 this.name = name; 113 this.flags = flags; 114 setArity(arity); 115 } 116 117 final int getArity() { 118 return arity; 119 } 120 121 final boolean isVariableArity() { 122 return (flags & IS_VARIABLE_ARITY) != 0; 123 } 124 125 final boolean isPropertyAccessor() { 126 return (flags & IS_PROPERTY_ACCESSOR) != 0; 127 } 128 129 /** 130 * Used from e.g. Native*$Constructors as an explicit call. TODO - make arity immutable and final 131 * @param arity new arity 132 */ 133 void setArity(final int arity) { 134 if(arity < 0 || arity > MAX_ARITY) { 135 throw new IllegalArgumentException(String.valueOf(arity)); 136 } 137 this.arity = arity; 138 } 139 140 CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) { 141 final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args); 142 143 if (isConstructor()) { 144 return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.createComposableConstructor(), fn, args), null); 145 } 146 147 return new CompiledFunction(boundInvoker); 148 } 149 150 /** 151 * Is this a ScriptFunction generated with strict semantics? 152 * @return true if strict, false otherwise 153 */ 154 public final boolean isStrict() { 155 return (flags & IS_STRICT) != 0; 156 } 157 | 53 // "byte arity" field can be widened. 54 assert MAX_ARITY < 256; 55 } 56 57 /** Name of the function or "" for anonymous functions */ 58 protected final String name; 59 60 /** 61 * A list of code versions of a function sorted in ascending order of generic descriptors. 62 */ 63 protected transient LinkedList<CompiledFunction> code = new LinkedList<>(); 64 65 /** Function flags */ 66 protected int flags; 67 68 // Parameter arity of the function, corresponding to "f.length". E.g. "function f(a, b, c) { ... }" arity is 3, and 69 // some built-in ECMAScript functions have their arity declared by the specification. Note that regardless of this 70 // value, the function might still be capable of receiving variable number of arguments, see isVariableArity. 71 private int arity; 72 73 // this may be null, if not available 74 private String documentation; 75 76 /** 77 * A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by 78 * multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are 79 * idempotent. 80 */ 81 private volatile transient GenericInvokers genericInvokers; 82 83 private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class); 84 85 /** Is this a strict mode function? */ 86 public static final int IS_STRICT = 1 << 0; 87 /** Is this a built-in function? */ 88 public static final int IS_BUILTIN = 1 << 1; 89 /** Is this a constructor function? */ 90 public static final int IS_CONSTRUCTOR = 1 << 2; 91 /** Does this function expect a callee argument? */ 92 public static final int NEEDS_CALLEE = 1 << 3; 93 /** Does this function make use of the this-object argument? */ 94 public static final int USES_THIS = 1 << 4; 95 /** Is this a variable arity function? */ 104 105 private static final long serialVersionUID = 4252901245508769114L; 106 107 /** 108 * Constructor 109 * 110 * @param name script function name 111 * @param arity arity 112 * @param flags the function flags 113 */ 114 ScriptFunctionData(final String name, final int arity, final int flags) { 115 this.name = name; 116 this.flags = flags; 117 setArity(arity); 118 } 119 120 final int getArity() { 121 return arity; 122 } 123 124 final String getDocumentation() { 125 return documentation != null? documentation : toSource(); 126 } 127 128 final boolean isVariableArity() { 129 return (flags & IS_VARIABLE_ARITY) != 0; 130 } 131 132 final boolean isPropertyAccessor() { 133 return (flags & IS_PROPERTY_ACCESSOR) != 0; 134 } 135 136 /** 137 * Used from e.g. Native*$Constructors as an explicit call. TODO - make arity immutable and final 138 * @param arity new arity 139 */ 140 void setArity(final int arity) { 141 if(arity < 0 || arity > MAX_ARITY) { 142 throw new IllegalArgumentException(String.valueOf(arity)); 143 } 144 this.arity = arity; 145 } 146 147 /** 148 * Used from nasgen generated code. 149 * 150 * @param doc documentation for this function 151 */ 152 void setDocumentation(final String doc) { 153 this.documentation = doc; 154 } 155 156 CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) { 157 final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args); 158 159 if (isConstructor()) { 160 return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.createComposableConstructor(), fn, args), null); 161 } 162 163 return new CompiledFunction(boundInvoker); 164 } 165 166 /** 167 * Is this a ScriptFunction generated with strict semantics? 168 * @return true if strict, false otherwise 169 */ 170 public final boolean isStrict() { 171 return (flags & IS_STRICT) != 0; 172 } 173 |