gt:     if (regexp.prototype == null)
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;
  
  /**
   * JavaScript object
   */
  class NativeRegexp extends Native {
    static ESId INDEX = ESId.intern("index");
    static ESId INPUT = ESId.intern("input");
  
    static final int NEW = 1;
    static final int COMPILE = NEW + 1;
    static final int EXEC = COMPILE + 1;
    static final int TEST = EXEC + 1;
    static final int TO_STRING = TEST + 1;
  
    /**
     * Create a new object based on a prototype
     */
    private NativeRegexp(String name, int n, int len)
    {
      super(name, len);
  
      this.n = n;
    }
  
    /**
     * Creates the native Regexp object
     */
    static ESRegexpWrapper create(Global resin)
    {
      NativeRegexp nativeRegexp = new NativeRegexp("Regexp", NEW, 1);
      ESRegexp proto;
  
      try {
        proto = new ESRegexp("", "");
      } catch (Exception e) {
        throw new RuntimeException();
      }
      proto.prototype = resin.objProto;
      resin.regexpProto = proto;
      ESRegexpWrapper regexp = new ESRegexpWrapper(resin, nativeRegexp, proto);
  
      put(proto, "exec", EXEC, 1);
      put(proto, "compile", COMPILE, 2);
      put(proto, "test", TEST, 1);
      put(proto, "toString", TO_STRING, 0);
  
      proto.setClean();
      regexp.setClean();
  
      return regexp;
    }
  
    static private void put(ESObject proto, String name, int n, int len)
    {
      ESId id = ESId.intern(name);
      NativeRegexp fun = new NativeRegexp(name, n, len);
  
      proto.put(id, fun, DONT_ENUM);
    }
  
    public ESBase call(Call eval, int length) throws Throwable
    {
      switch (n) {
      case NEW:
        return create(eval, length);
  
      case TO_STRING:
        try {
          ESRegexp regexp = (ESRegexp) eval.getThis();
          String s = regexp.pattern.toString();
          String f = regexp.flags.toString();
  
          return ESString.create("/" + s + "/" + f);
        } catch (ClassCastException e) {
          throw new ESException("toString expected regexp object");
        }
  
      case EXEC:
        return exec(eval, length);
  
      case COMPILE:
        return compile(eval, length);
  
      case TEST:
        return test(eval, length);
  
      default:
        throw new ESException("Unknown object function");
      }
    }
  
    private ESBase create(Call eval, int length) throws Throwable
    {
      ESString pattern;
      ESString flags = null;
  
      if (length == 0)
        pattern = ESString.NULL;
      else
        pattern = eval.getArg(0).toStr();
  
      if (length > 1)
        flags =  eval.getArg(1).toStr();
      else
        flags = ESString.NULL;
  
      ESObject obj;
      obj = new ESRegexp(pattern, flags);
  
      return obj;
    }
  
    private ESBase compile(Call eval, int length) throws Throwable
    {
      ESString pattern;
      ESString flags = null;
      ESBase arg = eval.getArg(-1);
  
      if (arg instanceof ESThunk)
        arg = ((ESThunk) arg).toObject();
  
      if (! (arg instanceof ESRegexp))
        throw new ESException("compile must be bound to regexp");
      ESRegexp regexp = (ESRegexp) arg;
  
      if (length == 0)
        return esUndefined;
      else
        pattern = eval.getArg(0).toStr();
  
      if (length > 1)
        flags =  eval.getArg(1).toStr();
      else
        flags = ESString.NULL;
  
      regexp.compile(pattern, flags);
  
      return regexp;
    }
  
    static ESBase exec(Call eval, int length) throws Throwable
    {
      ESBase reg = eval.getArg(-1);
      ESRegexp regexp;
  
      if (reg instanceof ESThunk)
        reg = ((ESThunk) reg).toObject();
  
      if (reg instanceof ESRegexp)
        regexp = (ESRegexp) reg;
      else
        regexp = new ESRegexp(reg.toStr(), ESString.NULL);
      if (regexp.prototype == null)
        throw new RuntimeException();
  
      ESString string;
  
      Global global = Global.getGlobalProto();
      if (length == 0)
        string = global.getRegexp().getProperty(global.getRegexp().INPUT).toStr();
      else
        string = eval.getArg(0).toStr();
  
      global.getRegexp().setRegexp(regexp);
      if (! regexp.exec(string))
        return esNull;
  
      return esNull;
      /* java.util.regex
        
      ESArray array = global.createArray();
      for (int i = 0; i < regexp.regexp.length(); i++) {
        int begin = regexp.regexp.getBegin(i);
        int end = regexp.regexp.getEnd(i);
        if (begin < end && begin >= 0)
          array.setProperty(i, string.substring(begin, end));
        else
          array.setProperty(i, ESString.create("")); // XXX: possible?
      }
  
      // java.util.regex
      // array.setProperty(INDEX, ESNumber.create(regexp.regexp.getBegin(0)));
      array.setProperty(INPUT, string);
  
      return array;
      */
    }
  
    private ESBase test(Call eval, int length) throws Throwable
    {
      ESBase reg = eval.getArg(-1);
      ESRegexp regexp;
  
      if (reg instanceof ESThunk)
        reg = ((ESThunk) reg).toObject();
  
      if (reg instanceof ESRegexp)
        regexp = (ESRegexp) reg;
      else
        regexp = new ESRegexp(reg.toStr(), ESString.NULL);
  