示例#1
0
  @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()));
    }
  }
示例#2
0
  public FunctionDescriptor parseFunction(ExecutionContext context, String code)
      throws RecognitionException {
    final ANTLRStringStream stream = new ANTLRStringStream(code);
    ES3Lexer lexer = new ES3Lexer(stream);

    CommonTokenStream lexerStream = new CommonTokenStream(lexer);
    ES3Parser parser = new ES3Parser(lexerStream);

    ES3Parser.functionExpression_return function = parser.functionExpression();
    List<String> errors = parser.getErrors();
    if (!errors.isEmpty()) {
      throw new ThrowException(context, context.createSyntaxError(errors.get(0)));
    }

    CommonTree tree = (CommonTree) function.getTree();
    CommonTreeNodeStream treeNodeStream = new CommonTreeNodeStream(tree);
    treeNodeStream.setTokenStream(lexerStream);
    ES3Walker walker = new ES3Walker(treeNodeStream);

    Executor executor = new Executor();
    executor.setBlockManager(context.getBlockManager());
    walker.setExecutor(executor);
    FunctionDescriptor descriptor = walker.functionDescriptor();
    return descriptor;
  }
示例#3
0
  @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()));
    }
  }