@Override public Object call(ExecutionContext context, Object self, Object... args) { // 15.3.2.1 int numArgs = args.length; String body = ""; if (numArgs > 0) { body = Types.toString(context, args[numArgs - 1]); } StringBuffer formalParams = new StringBuffer(); boolean first = true; Set<String> seenParams = new HashSet<>(); boolean duplicateFormalParams = false; for (int i = 0; i < numArgs - 1; ++i) { if (!first) { formalParams.append(","); } String param = Types.toString(context, args[i]); if (seenParams.contains(param)) { duplicateFormalParams = true; } seenParams.add(param); formalParams.append(param); first = false; } StringBuffer code = new StringBuffer(); code.append("function(" + formalParams.toString() + "){\n"); code.append(body); code.append("}"); try { FunctionDescriptor descriptor = parseFunction(context, code.toString()); JSCompiler compiler = context.getGlobalObject().getCompiler(); JSFunction function = compiler.compileFunction( context, descriptor.getFormalParameters(), descriptor.getBlock(), false); if (function.isStrict() && duplicateFormalParams) { throw new ThrowException( context, context.createSyntaxError("duplicate formal parameters in function definition")); } function.setPrototype(getPrototype()); return function; } catch (RecognitionException e) { throw new ThrowException(context, context.createSyntaxError(e.getMessage())); } }
@Override public Object call(ExecutionContext context, Object self, Object... args) { // 15.3.2.1 int numArgs = args.length; String body = ""; StringBuilder formalParams = new StringBuilder(); boolean first = true; Set<String> seenParams = new HashSet<>(); boolean duplicateFormalParams = false; for (int i = 0; i < numArgs - 1; ++i) { String paramStr = Types.toString(context, args[i]); StringTokenizer paramTokens = new StringTokenizer(paramStr, ","); while (paramTokens.hasMoreTokens()) { if (!first) { formalParams.append(","); } String param = paramTokens.nextToken().trim(); if (seenParams.contains(param)) { duplicateFormalParams = true; } seenParams.add(param); formalParams.append(param); first = false; } } if (numArgs > 0) { body = Types.toString(context, args[numArgs - 1]); } StringBuilder code = new StringBuilder(); code.append("function(" + formalParams.toString() + "){\n"); code.append(body); code.append("}"); try { FunctionDescriptor descriptor = parseFunction(context, code.toString()); JSCompiler compiler = context.getGlobalObject().getCompiler(); JSFunction function = compiler.compileFunction( context, descriptor.getIdentifier(), descriptor.getFormalParameterNames(), descriptor.getBlock(), descriptor.isStrict()); if (function.isStrict()) { if (duplicateFormalParams) { throw new ThrowException( context, context.createSyntaxError("duplicate formal parameters in function definition")); } if (seenParams.contains("eval")) { throw new ThrowException( context, context.createSyntaxError( "formal parameter 'eval' not allowed in function definition in strict-mode")); } } function.setPrototype(getPrototype()); return function; } catch (ParserException e) { throw new ThrowException(context, context.createSyntaxError(e.getMessage())); } catch (IOException e) { throw new ThrowException(context, context.createSyntaxError(e.getMessage())); } }