gt:     for (int i = 0; i < scopeLength; i++)
context: /*
   * Copyright (c) 1998-2012 Caucho Technology -- all rights reserved
   *
   * This file is part of Resin(R) Open Source
   *
   * Each copy or derived work must preserve the copyright notice and this
   * notice unmodified.
   *
   * Resin Open Source is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * Resin Open Source 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, or any warranty
   * of NON-INFRINGEMENT.  See the GNU General Public License for more
   * details.
   *
   * You should have received a copy of the GNU General Public License
   * along with Resin Open Source; if not, write to the
   *   Free SoftwareFoundation, Inc.
   *   59 Temple Place, Suite 330
   *   Boston, MA 02111-1307  USA
   *
   * @author Scott Ferguson
   */
  
  package com.caucho.es;
  
  import com.caucho.util.Exit;
  
  /**
   * ScriptClosure lets Java programs call JavaScript functions.  It contains
   * the state of an executing JavaScript program. 
   */
  final public class ScriptClosure {
    private Script script;
    private Global resin;
    private ESGlobal global;
  
    ScriptClosure(Global resin, ESGlobal global, Script script)
    {
      this.script = script;
      this.resin = resin;
      this.global = global;
    }
  
    /**
     * Returns the lastModified time of the script.  The last modified
     * time is the maximum of all imported script modified times.
     *
     * <p>getLastModified is vital for dynamic applications like JSP
     * which need to reload the script when it changes.
     */
    public boolean isModified()
    {
      return script.isModified();
    }
  
    /**
     * Calls the JavaScript function 'name' with no arguments.
     *
     * @param name JavaScript function name.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.top = 1;
      call.setArg(-1, global);
  
      Object value = call(getFunction(name), call, 0);
  
      resin.freeCall(call);
  
      return value;
    }
  
    /**
     * Calls the JavaScript function 'name' with a single argument.
     * <p>Arguments are automatically wrapped, and return values automatically
     * unwrapped.
     *
     * @param name JavaScript function name.
     * @param a First argument passed to JavaScript.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name, Object a)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.top = 1;
      call.setArg(-1, global);
      call.setArg(0, resin.objectWrap(a));
  
      Object value = call(getFunction(name), call, 1);
  
      resin.freeCall(call);
  
      return value;
    }
  
    /**
     * Calls the JavaScript function 'name' with two arguments.
     * <p>Arguments are automatically wrapped, and return values automatically
     * unwrapped.
     *
     * @param name JavaScript function name.
     * @param a First argument passed to JavaScript.
     * @param b Second argument passed to JavaScript.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name, Object a, Object b)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.top = 1;
      call.setArg(-1, global);
      call.setArg(0, resin.objectWrap(a));
      call.setArg(1, resin.objectWrap(b));
  
      Object value = call(getFunction(name), call, 2);
  
      resin.freeCall(call);
  
      return value;
    }
  
    /**
     * Calls the JavaScript function 'name' with three arguments.
     * <p>Arguments are automatically wrapped, and return values automatically
     * unwrapped.
     *
     * @param name JavaScript function name.
     * @param a First argument passed to JavaScript.
     * @param b Second argument passed to JavaScript.
     * @param c Third argument passed to JavaScript.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name, Object a, Object b, Object c)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.top = 1;
      call.setArg(-1, global);
      call.setArg(0, resin.objectWrap(a));
      call.setArg(1, resin.objectWrap(b));
      call.setArg(2, resin.objectWrap(c));
  
      Object value = call(getFunction(name), call, 3);
  
      resin.freeCall(call);
  
      return value;
    }
  
    /**
     * Calls the JavaScript function 'name' with four arguments.
     * <p>Arguments are automatically wrapped, and return values automatically
     * unwrapped.
     *
     * @param name JavaScript function name.
     * @param a First argument passed to JavaScript.
     * @param b Second argument passed to JavaScript.
     * @param c Third argument passed to JavaScript.
     * @param d Fourth argument passed to JavaScript.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name, Object a, Object b,
                                    Object c, Object d)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.top = 1;
      call.setArg(-1, global);
      call.setArg(0, resin.objectWrap(a));
      call.setArg(1, resin.objectWrap(b));
      call.setArg(2, resin.objectWrap(c));
      call.setArg(3, resin.objectWrap(d));
  
      Object value = call(getFunction(name), call, 4);
  
      resin.freeCall(call);
  
      return value;
    }
  
    /**
     * Calls the JavaScript function 'name' with an array of arguments.
     * <p>Arguments are automatically wrapped, and return values automatically
     * unwrapped.
     *
     * @param name JavaScript function name.
     * @param args Arguments to pass to the JavaScript function.
     * @return The Java object returned by the JavaScript function.
     */
    public synchronized Object call(String name, Object []args)
      throws Throwable
    {
      Call call = resin.getCall();
      call.caller = call;
      call.setArg(0, global);
      call.top = 1;
      for (int i = 0; i < args.length; i++)
        call.setArg(i, resin.objectWrap(args[i]));
  
      Object value = call(getFunction(name), call, args.length);
  
      resin.freeCall(call);
  
      return value;
    }
  
    private ESClosure getFunction(String name)
      throws Throwable
    {
      ESBase fun = global.hasProperty(ESString.create(name));
  
      if (fun == null)
        throw new ESException("no such function `" + name + "'");
  
      if (! (fun instanceof ESClosure))
        throw new ESException(name + " should be function: " + fun);
  
      return (ESClosure) fun;
    }
  
    private Object call(ESClosure closure, Call call, int length)
      throws Throwable
    {
      int scopeLength = closure.scopeLength;
      call.scopeLength = scopeLength;
  