home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 November / PCONLINE_11_99.ISO / filesbbs / OS2 / APCHSSL2.ZIP / OS2HTTPD / jserv / com / netscape / javascript / ScriptableObject.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-04-09  |  14.1 KB  |  882 lines

  1. package com.netscape.javascript;
  2.  
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Member;
  6. import java.lang.reflect.Method;
  7. import java.lang.reflect.Modifier;
  8. import java.util.Hashtable;
  9.  
  10. public abstract class ScriptableObject implements Scriptable {
  11.    public static final int EMPTY = 0;
  12.    public static final int READONLY = 1;
  13.    public static final int DONTENUM = 2;
  14.    public static final int PERMANENT = 4;
  15.    private static final int SLOT_NOT_FOUND = -1;
  16.    protected Scriptable prototype;
  17.    protected Scriptable parent;
  18.    private static final Object HAS_STATIC_ACCESSORS;
  19.    private static final Slot REMOVED;
  20.    private static Hashtable exclusionList;
  21.    private Slot[] slots;
  22.    private int count;
  23.    private String lastName;
  24.    private int lastHash;
  25.    private Object lastValue;
  26.    // $FF: synthetic field
  27.    private static Class class$com$netscape$javascript$ScriptableObject;
  28.    // $FF: synthetic field
  29.    private static Class class$com$netscape$javascript$Scriptable;
  30.    // $FF: synthetic field
  31.    private static Class class$com$netscape$javascript$Function;
  32.    // $FF: synthetic field
  33.    private static Class class$com$netscape$javascript$FunctionObject;
  34.  
  35.    public abstract String getClassName();
  36.  
  37.    public void put(String var1, Scriptable var2, Object var3) {
  38.       int var4 = var1.hashCode();
  39.       int var5 = this.getSlot(var1, var4);
  40.       if (var5 == -1) {
  41.          if (var2 != this) {
  42.             ((Scriptable)var2).put(var1, (Scriptable)var2, var3);
  43.             return;
  44.          }
  45.  
  46.          var5 = this.getSlotToSet(var1, var4, false);
  47.       }
  48.  
  49.       Slot var6 = this.slots[var5];
  50.       if ((var6.attributes & 1) == 0) {
  51.          if ((var6.flags & 2) != 0) {
  52.             GetterSlot var7 = (GetterSlot)var6;
  53.  
  54.             try {
  55.                if (var7.delegateTo != null) {
  56.                   Object[] var12 = new Object[]{this, var3};
  57.                   var7.setter.invoke(var7.delegateTo, var12);
  58.                } else {
  59.                   Object[] var8 = new Object[]{var3};
  60.                   Class var9 = var7.setter.getDeclaringClass();
  61.  
  62.                   while(!var9.isInstance(var2)) {
  63.                      var2 = ((Scriptable)var2).getPrototype();
  64.                      if (var2 == null) {
  65.                         var2 = this;
  66.                         break;
  67.                      }
  68.                   }
  69.  
  70.                   var7.setter.invoke(var2, var8);
  71.                }
  72.             } catch (InvocationTargetException var10) {
  73.                throw WrappedException.wrapException(var10);
  74.             } catch (IllegalAccessException var11) {
  75.                throw WrappedException.wrapException(var11);
  76.             }
  77.          } else if (this == var2) {
  78.             var6.value = var3;
  79.             this.lastValue = var1 == this.lastName ? var3 : REMOVED;
  80.          } else {
  81.             ((Scriptable)var2).put(var1, (Scriptable)var2, var3);
  82.          }
  83.       }
  84.    }
  85.  
  86.    public void put(int var1, Scriptable var2, Object var3) {
  87.       int var4 = this.getSlot((String)null, var1);
  88.       if (var4 == -1) {
  89.          if (var2 != this) {
  90.             var2.put(var1, var2, var3);
  91.             return;
  92.          }
  93.  
  94.          var4 = this.getSlotToSet((String)null, var1, false);
  95.       }
  96.  
  97.       Slot var5 = this.slots[var4];
  98.       if ((var5.attributes & 1) == 0) {
  99.          if (this == var2) {
  100.             var5.value = var3;
  101.          } else {
  102.             var2.put(var1, var2, var3);
  103.          }
  104.       }
  105.    }
  106.  
  107.    public Scriptable getParentScope() {
  108.       return this.parent;
  109.    }
  110.  
  111.    public void setParentScope(Scriptable var1) {
  112.       this.parent = var1;
  113.    }
  114.  
  115.    public static Scriptable getFunctionPrototype(Scriptable var0) {
  116.       return getClassPrototype(var0, "Function");
  117.    }
  118.  
  119.    public static Scriptable getClassPrototype(Scriptable var0, String var1) {
  120.       var0 = getTopLevelScope(var0);
  121.       if (!var0.has(var1, var0)) {
  122.          return null;
  123.       } else {
  124.          Object var2 = var0.get(var1, var0);
  125.          if (!(var2 instanceof Scriptable)) {
  126.             return null;
  127.          } else {
  128.             Scriptable var3 = (Scriptable)var2;
  129.             if (!var3.has("prototype", var3)) {
  130.                return null;
  131.             } else {
  132.                Object var4 = var3.get("prototype", var3);
  133.                return !(var4 instanceof Scriptable) ? null : (Scriptable)var4;
  134.             }
  135.          }
  136.       }
  137.    }
  138.  
  139.    private int getSlot(String var1, int var2) {
  140.       if (this.slots == null) {
  141.          return -1;
  142.       } else {
  143.          int var3 = (var2 & Integer.MAX_VALUE) % this.slots.length;
  144.          int var4 = var3;
  145.  
  146.          do {
  147.             Slot var5 = this.slots[var4];
  148.             if (var5 == null) {
  149.                return -1;
  150.             }
  151.  
  152.             if (var5 != REMOVED && var5.intKey == var2 && (var5.stringKey == var1 || var1 != null && var1.equals(var5.stringKey))) {
  153.                return var4;
  154.             }
  155.  
  156.             ++var4;
  157.             if (var4 == this.slots.length) {
  158.                var4 = 0;
  159.             }
  160.          } while(var4 != var3);
  161.  
  162.          return -1;
  163.       }
  164.    }
  165.  
  166.    private static Object rescopeValue(Object var0, Hashtable var1) {
  167.       if (var0 == null) {
  168.          return null;
  169.       } else {
  170.          try {
  171.             return ((Rescopeable)var0).rescope(var1);
  172.          } catch (ClassCastException var2) {
  173.             throw new RuntimeException("Can't rescope value " + var0);
  174.          }
  175.       }
  176.    }
  177.  
  178.    public static Scriptable getObjectPrototype(Scriptable var0) {
  179.       return getClassPrototype(var0, "Object");
  180.    }
  181.  
  182.    public void defineProperty(String var1, Object var2, int var3) {
  183.       this.put(var1, this, var2);
  184.  
  185.       try {
  186.          this.setAttributes(var1, this, var3);
  187.       } catch (PropertyException var4) {
  188.          throw new RuntimeException("Cannot create property");
  189.       }
  190.    }
  191.  
  192.    public void defineProperty(String var1, Class var2, int var3) throws PropertyException {
  193.       StringBuffer var4 = new StringBuffer(var1);
  194.       var4.setCharAt(0, Character.toUpperCase(var1.charAt(0)));
  195.       String var5 = var4.toString();
  196.       Method[] var6 = FunctionObject.findMethods(var2, "get" + var5);
  197.       Method[] var7 = FunctionObject.findMethods(var2, "set" + var5);
  198.       if (var7 == null) {
  199.          var3 |= 1;
  200.       }
  201.  
  202.       if (var6.length == 1 && (var7 == null || var7.length == 1)) {
  203.          this.defineProperty(var1, (Object)null, var6[0], var7 == null ? null : var7[0], var3);
  204.       } else {
  205.          Object[] var8 = new Object[]{var1, var2.getName()};
  206.          throw new PropertyException(Context.getMessage("msg.no.overload", var8));
  207.       }
  208.    }
  209.  
  210.    public void defineProperty(String var1, Object var2, Method var3, Method var4, int var5) throws PropertyException {
  211.       short var6 = 1;
  212.       if (var2 == null && Modifier.isStatic(var3.getModifiers())) {
  213.          var2 = HAS_STATIC_ACCESSORS;
  214.       }
  215.  
  216.       Class[] var7 = var3.getParameterTypes();
  217.       if (var7.length != 0) {
  218.          if (var7.length != 1 || var7[0] != (class$com$netscape$javascript$ScriptableObject != null ? class$com$netscape$javascript$ScriptableObject : (class$com$netscape$javascript$ScriptableObject = class$("com.netscape.javascript.ScriptableObject")))) {
  219.             Object[] var8 = new Object[]{var3.toString()};
  220.             throw new PropertyException(Context.getMessage("msg.bad.getter.parms", var8));
  221.          }
  222.       } else if (var2 != null) {
  223.          Object[] var14 = new Object[]{var3.toString()};
  224.          throw new PropertyException(Context.getMessage("msg.obj.getter.parms", var14));
  225.       }
  226.  
  227.       if (var4 != null) {
  228.          var6 = (short)(var6 | 2);
  229.          if (var2 == HAS_STATIC_ACCESSORS != Modifier.isStatic(var4.getModifiers())) {
  230.             throw new PropertyException(Context.getMessage("msg.getter.static", (Object[])null));
  231.          }
  232.  
  233.          var7 = var4.getParameterTypes();
  234.          if (var7.length == 2) {
  235.             if (var7[0] != (class$com$netscape$javascript$ScriptableObject != null ? class$com$netscape$javascript$ScriptableObject : (class$com$netscape$javascript$ScriptableObject = class$("com.netscape.javascript.ScriptableObject")))) {
  236.                throw new PropertyException(Context.getMessage("msg.setter2.parms", (Object[])null));
  237.             }
  238.  
  239.             if (var2 == null) {
  240.                Object[] var11 = new Object[]{var4.toString()};
  241.                throw new PropertyException(Context.getMessage("msg.setter1.parms", var11));
  242.             }
  243.          } else {
  244.             if (var7.length != 1) {
  245.                throw new PropertyException(Context.getMessage("msg.setter.parms", (Object[])null));
  246.             }
  247.  
  248.             if (var2 != null) {
  249.                Object[] var13 = new Object[]{var4.toString()};
  250.                throw new PropertyException(Context.getMessage("msg.setter2.expected", var13));
  251.             }
  252.          }
  253.       }
  254.  
  255.       int var12 = this.getSlotToSet(var1, var1.hashCode(), true);
  256.       GetterSlot var9 = (GetterSlot)this.slots[var12];
  257.       var9.delegateTo = var2;
  258.       var9.getter = var3;
  259.       var9.setter = var4;
  260.       var9.value = null;
  261.       var9.attributes = (short)var5;
  262.       var9.flags = var6;
  263.    }
  264.  
  265.    public boolean has(String var1, Scriptable var2) {
  266.       return this.getSlot(var1, var1.hashCode()) != -1;
  267.    }
  268.  
  269.    public boolean has(int var1, Scriptable var2) {
  270.       return this.getSlot((String)null, var1) != -1;
  271.    }
  272.  
  273.    public Object[] getIds() {
  274.       if (this.slots == null) {
  275.          return ScriptRuntime.emptyArgs;
  276.       } else {
  277.          int var1 = 0;
  278.  
  279.          for(int var2 = this.slots.length - 1; var2 >= 0; --var2) {
  280.             Slot var3 = this.slots[var2];
  281.             if (var3 != null && var3 != REMOVED && (var3.attributes & 2) == 0) {
  282.                ++var1;
  283.             }
  284.          }
  285.  
  286.          Object[] var5 = new Object[var1];
  287.  
  288.          for(int var6 = this.slots.length - 1; var6 >= 0; --var6) {
  289.             Slot var4 = this.slots[var6];
  290.             if (var4 != null && var4 != REMOVED && (var4.attributes & 2) == 0) {
  291.                --var1;
  292.                var5[var1] = var4.stringKey != null ? var4.stringKey : new Integer(var4.intKey);
  293.             }
  294.          }
  295.  
  296.          return var5;
  297.       }
  298.    }
  299.  
  300.    protected synchronized Scriptable rescope(Hashtable var1) {
  301.       Scriptable var2 = (Scriptable)var1.get(this);
  302.       if (var2 != null) {
  303.          return var2;
  304.       } else {
  305.          ScriptableObject var3 = null;
  306.  
  307.          try {
  308.             var3 = (ScriptableObject)this.clone();
  309.          } catch (CloneNotSupportedException var6) {
  310.          }
  311.  
  312.          var1.put(this, var3);
  313.          var3.parent = (Scriptable)rescopeValue(this.parent, var1);
  314.          var3.prototype = (Scriptable)rescopeValue(this.prototype, var1);
  315.          if (this.slots == null) {
  316.             return var3;
  317.          } else {
  318.             var3.slots = new Slot[this.slots.length];
  319.  
  320.             for(int var4 = 0; var4 < this.slots.length; ++var4) {
  321.                if (this.slots[var4] != null) {
  322.                   Object var5 = this.slots[var4].value;
  323.                   if (var5 instanceof Scriptable) {
  324.                      var2 = (Scriptable)var1.get(var5);
  325.                      if (var2 == null) {
  326.                         var3.slots[var4] = new RescopingSlot(this.slots[var4], var1);
  327.                         continue;
  328.                      }
  329.  
  330.                      var5 = var2;
  331.                   }
  332.  
  333.                   var3.slots[var4] = (Slot)this.slots[var4].clone();
  334.                   var3.slots[var4].value = var5;
  335.                }
  336.             }
  337.  
  338.             return var3;
  339.          }
  340.       }
  341.    }
  342.  
  343.    private synchronized int addSlot(String var1, int var2, boolean var3) {
  344.       int var4 = (var2 & Integer.MAX_VALUE) % this.slots.length;
  345.       int var5 = var4;
  346.  
  347.       while(true) {
  348.          Slot var6 = this.slots[var5];
  349.          if (var6 != null && var6 != REMOVED) {
  350.             if (var6.intKey != var2 || var6.stringKey != var1 && (var1 == null || !var1.equals(var6.stringKey))) {
  351.                ++var5;
  352.                if (var5 == this.slots.length) {
  353.                   var5 = 0;
  354.                }
  355.  
  356.                if (var5 == var4) {
  357.                   throw new RuntimeException("Hashtable internal error");
  358.                }
  359.                continue;
  360.             }
  361.  
  362.             return var5;
  363.          }
  364.  
  365.          ++this.count;
  366.          if (4 * this.count > 3 * this.slots.length) {
  367.             this.grow();
  368.             return this.getSlotToSet(var1, var2, var3);
  369.          }
  370.  
  371.          var6 = (Slot)(var3 ? new GetterSlot() : new Slot());
  372.          var6.stringKey = var1;
  373.          var6.intKey = var2;
  374.          this.slots[var5] = var6;
  375.          return var5;
  376.       }
  377.    }
  378.  
  379.    public boolean hasInstance(Scriptable var1) {
  380.       return ScriptRuntime.jsDelegatesTo(var1, this);
  381.    }
  382.  
  383.    public Object get(String var1, Scriptable var2) {
  384.       int var3;
  385.       if (var1 == this.lastName) {
  386.          if (this.lastValue != REMOVED) {
  387.             return this.lastValue;
  388.          }
  389.  
  390.          var3 = this.lastHash;
  391.       } else {
  392.          var3 = var1.hashCode();
  393.       }
  394.  
  395.       int var4 = this.getSlot(var1, var3);
  396.       if (var4 == -1) {
  397.          return Scriptable.NOT_FOUND;
  398.       } else {
  399.          Slot var5 = this.slots[var4];
  400.          if ((var5.flags & 4) != 0) {
  401.             var5.value = rescopeValue(var5.value, ((RescopingSlot)var5).ht);
  402.             var5.flags = (short)(var5.flags & -5);
  403.          }
  404.  
  405.          if ((var5.flags & 1) != 0) {
  406.             GetterSlot var6 = (GetterSlot)var5;
  407.  
  408.             try {
  409.                if (var6.delegateTo != null) {
  410.                   Object[] var10 = new Object[]{this};
  411.                   return var6.getter.invoke(var6.delegateTo, var10);
  412.                } else {
  413.                   Class var7 = var6.getter.getDeclaringClass();
  414.  
  415.                   while(!var7.isInstance(var2)) {
  416.                      var2 = ((Scriptable)var2).getPrototype();
  417.                      if (var2 == null) {
  418.                         var2 = this;
  419.                         break;
  420.                      }
  421.                   }
  422.  
  423.                   return var6.getter.invoke(var2, ScriptRuntime.emptyArgs);
  424.                }
  425.             } catch (InvocationTargetException var8) {
  426.                throw WrappedException.wrapException(var8);
  427.             } catch (IllegalAccessException var9) {
  428.                throw WrappedException.wrapException(var9);
  429.             }
  430.          } else {
  431.             this.lastValue = REMOVED;
  432.             this.lastName = var1;
  433.             this.lastHash = var3;
  434.             this.lastValue = var5.value;
  435.             return this.lastValue;
  436.          }
  437.       }
  438.    }
  439.  
  440.    public Object get(int var1, Scriptable var2) {
  441.       int var3 = this.getSlot((String)null, var1);
  442.       return var3 == -1 ? Scriptable.NOT_FOUND : this.slots[var3].value;
  443.    }
  444.  
  445.    public Object getDefaultValue(Class var1) {
  446.       FlattenedObject var3 = new FlattenedObject(this);
  447.       Context var4 = null;
  448.  
  449.       try {
  450.          int var5 = 0;
  451.  
  452.          do {
  453.             label123: {
  454.                Object var2;
  455.                if (var1 == ScriptRuntime.StringClass ? var5 == 0 : var5 == 1) {
  456.                   Function var6 = this.getFunctionProperty(var3, "toString");
  457.                   if (var6 == null) {
  458.                      break label123;
  459.                   }
  460.  
  461.                   if (var4 == null) {
  462.                      var4 = Context.getContext();
  463.                   }
  464.  
  465.                   var2 = var6.call(var4, var6.getParentScope(), var3.getObject(), ScriptRuntime.emptyArgs);
  466.                } else {
  467.                   String var11;
  468.                   if (var1 == null) {
  469.                      var11 = "undefined";
  470.                   } else if (var1 == ScriptRuntime.StringClass) {
  471.                      var11 = "string";
  472.                   } else if (var1 == ScriptRuntime.ScriptableClass) {
  473.                      var11 = "object";
  474.                   } else if (var1 == ScriptRuntime.FunctionClass) {
  475.                      var11 = "function";
  476.                   } else if (var1 != ScriptRuntime.BooleanClass && var1 != Boolean.TYPE) {
  477.                      if (var1 != ScriptRuntime.NumberClass && var1 != ScriptRuntime.ByteClass && var1 != Byte.TYPE && var1 != ScriptRuntime.ShortClass && var1 != Short.TYPE && var1 != ScriptRuntime.IntegerClass && var1 != Integer.TYPE && var1 != ScriptRuntime.FloatClass && var1 != Float.TYPE && var1 != ScriptRuntime.DoubleClass && var1 != Double.TYPE) {
  478.                         Object[] var7 = new Object[]{var1.toString()};
  479.                         throw Context.reportRuntimeError(Context.getMessage("msg.invalid.type", var7));
  480.                      }
  481.  
  482.                      var11 = "number";
  483.                   } else {
  484.                      var11 = "boolean";
  485.                   }
  486.  
  487.                   Function var13 = this.getFunctionProperty(var3, "valueOf");
  488.                   if (var13 == null) {
  489.                      break label123;
  490.                   }
  491.  
  492.                   Object[] var8 = new Object[]{var11};
  493.                   if (var4 == null) {
  494.                      var4 = Context.getContext();
  495.                   }
  496.  
  497.                   var2 = var13.call(var4, var13.getParentScope(), var3.getObject(), var8);
  498.                }
  499.  
  500.                if (var2 != null && (var2 == Undefined.instance || !(var2 instanceof Scriptable) || var1 == (class$com$netscape$javascript$Scriptable != null ? class$com$netscape$javascript$Scriptable : (class$com$netscape$javascript$Scriptable = class$("com.netscape.javascript.Scriptable"))) || var1 == (class$com$netscape$javascript$Function != null ? class$com$netscape$javascript$Function : (class$com$netscape$javascript$Function = class$("com.netscape.javascript.Function"))))) {
  501.                   return var2;
  502.                }
  503.             }
  504.  
  505.             ++var5;
  506.          } while(var5 < 2);
  507.       } catch (JavaScriptException var9) {
  508.       }
  509.  
  510.       String var10 = var1 == null ? "undefined" : var1.toString();
  511.       Object[] var12 = new Object[]{var10};
  512.       throw Context.reportRuntimeError(Context.getMessage("msg.default.value", var12));
  513.    }
  514.  
  515.    public ScriptableObject() {
  516.       this.lastValue = REMOVED;
  517.    }
  518.  
  519.    public Scriptable getPrototype() {
  520.       return this.prototype;
  521.    }
  522.  
  523.    public void setPrototype(Scriptable var1) {
  524.       this.prototype = var1;
  525.    }
  526.  
  527.    public int getAttributes(String var1, Scriptable var2) throws PropertyException {
  528.       int var3 = this.getSlot(var1, var1.hashCode());
  529.       if (var3 == -1) {
  530.          throw new PropertyException(Context.getMessage("msg.prop.not.found", (Object[])null));
  531.       } else {
  532.          return this.slots[var3].attributes;
  533.       }
  534.    }
  535.  
  536.    public int getAttributes(int var1, Scriptable var2) throws PropertyException {
  537.       int var3 = this.getSlot((String)null, var1);
  538.       if (var3 == -1) {
  539.          throw new PropertyException(Context.getMessage("msg.prop.not.found", (Object[])null));
  540.       } else {
  541.          return this.slots[var3].attributes;
  542.       }
  543.    }
  544.  
  545.    public void setAttributes(String var1, Scriptable var2, int var3) throws PropertyException {
  546.       boolean var4 = true;
  547.       var3 &= 7;
  548.       int var5 = this.getSlot(var1, var1.hashCode());
  549.       if (var5 == -1) {
  550.          throw new PropertyException(Context.getMessage("msg.prop.not.found", (Object[])null));
  551.       } else {
  552.          this.slots[var5].attributes = (short)var3;
  553.       }
  554.    }
  555.  
  556.    public void setAttributes(int var1, Scriptable var2, int var3) throws PropertyException {
  557.       int var4 = this.getSlot((String)null, var1);
  558.       if (var4 == -1) {
  559.          throw new PropertyException(Context.getMessage("msg.prop.not.found", (Object[])null));
  560.       } else {
  561.          this.slots[var4].attributes = (short)var3;
  562.       }
  563.    }
  564.  
  565.    public void defineFunctionProperties(String[] var1, Class var2, int var3) throws PropertyException {
  566.       for(int var4 = 0; var4 < var1.length; ++var4) {
  567.          String var5 = var1[var4];
  568.          Method[] var6 = FunctionObject.findMethods(var2, var5);
  569.          if (var6 == null) {
  570.             Object[] var9 = new Object[]{var5, var2.getName()};
  571.             throw new PropertyException(Context.getMessage("msg.method.not.found", var9));
  572.          }
  573.  
  574.          if (var6.length > 1) {
  575.             Object[] var8 = new Object[]{var5, var2.getName()};
  576.             throw new PropertyException(Context.getMessage("msg.no.overload", var8));
  577.          }
  578.  
  579.          FunctionObject var7 = new FunctionObject(var5, var6[0], this);
  580.          this.defineProperty(var5, (Object)var7, var3);
  581.       }
  582.  
  583.    }
  584.  
  585.    private Function getFunctionProperty(FlattenedObject var1, String var2) {
  586.       Object var3 = var1.getProperty(var2);
  587.       if (var3 != null && var3 instanceof FlattenedObject) {
  588.          Scriptable var4 = ((FlattenedObject)var3).getObject();
  589.          return var4 instanceof Function ? (Function)var4 : null;
  590.       } else {
  591.          return null;
  592.       }
  593.    }
  594.  
  595.    private static Hashtable getExclusionList() {
  596.       if (exclusionList != null) {
  597.          return exclusionList;
  598.       } else {
  599.          Hashtable var0 = new Hashtable(17);
  600.          Method[] var1 = ScriptRuntime.FunctionClass.getMethods();
  601.  
  602.          for(int var2 = 0; var2 < var1.length; ++var2) {
  603.             var0.put(var1[var2].getName(), Boolean.TRUE);
  604.          }
  605.  
  606.          exclusionList = var0;
  607.          return var0;
  608.       }
  609.    }
  610.  
  611.    private int getSlotToSet(String var1, int var2, boolean var3) {
  612.       if (this.slots == null) {
  613.          this.slots = new Slot[5];
  614.       }
  615.  
  616.       int var4 = (var2 & Integer.MAX_VALUE) % this.slots.length;
  617.       int var5 = var4;
  618.  
  619.       do {
  620.          Slot var6 = this.slots[var5];
  621.          if (var6 == null) {
  622.             return this.addSlot(var1, var2, var3);
  623.          }
  624.  
  625.          if (var6 != REMOVED && var6.intKey == var2 && (var6.stringKey == var1 || var1 != null && var1.equals(var6.stringKey))) {
  626.             return var5;
  627.          }
  628.  
  629.          ++var5;
  630.          if (var5 == this.slots.length) {
  631.             var5 = 0;
  632.          }
  633.       } while(var5 != var4);
  634.  
  635.       throw new RuntimeException("Hashtable internal error");
  636.    }
  637.  
  638.    static {
  639.       HAS_STATIC_ACCESSORS = Void.TYPE;
  640.       REMOVED = new Slot();
  641.       exclusionList = null;
  642.    }
  643.  
  644.    public static void defineClass(Scriptable var0, Class var1) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassDefinitionException, PropertyException {
  645.       Method[] var2 = var1.getMethods();
  646.  
  647.       for(int var3 = 0; var3 < var2.length; ++var3) {
  648.          if (var2[var3].getName().equals("init")) {
  649.             Class[] var4 = var2[var3].getParameterTypes();
  650.             if (var4.length == 1 && var4[0] == ScriptRuntime.ScriptableClass && Modifier.isStatic(var2[var3].getModifiers())) {
  651.                Object[] var5 = new Object[]{var0};
  652.                var2[var3].invoke((Object)null, var5);
  653.                return;
  654.             }
  655.          }
  656.       }
  657.  
  658.       Hashtable var25 = getExclusionList();
  659.       Constructor[] var26 = var1.getConstructors();
  660.       Constructor var27 = null;
  661.  
  662.       for(int var6 = 0; var6 < var26.length; ++var6) {
  663.          if (var26[var6].getParameterTypes().length == 0) {
  664.             var27 = var26[var6];
  665.             break;
  666.          }
  667.       }
  668.  
  669.       if (var27 == null) {
  670.          Object[] var29 = new Object[]{var1.getName()};
  671.          throw new ClassDefinitionException(Context.getMessage("msg.zero.arg.ctor", var29));
  672.       } else {
  673.          Scriptable var28 = (Scriptable)var27.newInstance(ScriptRuntime.emptyArgs);
  674.          var28.setPrototype(getObjectPrototype(var0));
  675.          String var7 = var28.getClassName();
  676.          String var8 = "js_";
  677.          String var9 = "jsFunction_";
  678.          String var10 = "jsProperty_";
  679.          boolean var11 = false;
  680.          Object var12 = null;
  681.  
  682.          for(int var13 = 0; var13 < var2.length; ++var13) {
  683.             String var14 = var2[var13].getName();
  684.             String var15 = null;
  685.             if (var14.startsWith("js_")) {
  686.                var15 = "js_";
  687.             }
  688.  
  689.             if (var14.startsWith("jsFunction_")) {
  690.                var15 = "jsFunction_";
  691.             }
  692.  
  693.             if (var14.startsWith("jsProperty_")) {
  694.                var15 = "jsProperty_";
  695.             }
  696.  
  697.             if (var15 != null) {
  698.                var11 = true;
  699.                var14 = var14.substring(var15.length());
  700.             }
  701.  
  702.             if (var14.equals(var7)) {
  703.                if (var12 != null) {
  704.                   Object[] var16 = new Object[]{var12, var2[var13]};
  705.                   throw new ClassDefinitionException(Context.getMessage("msg.multiple.ctors", var16));
  706.                }
  707.  
  708.                var12 = var2[var13];
  709.             }
  710.          }
  711.  
  712.          if (var12 == null) {
  713.             if (var26.length == 1) {
  714.                var12 = var26[0];
  715.             } else if (var26.length == 2) {
  716.                if (var26[0].getParameterTypes().length == 0) {
  717.                   var12 = var26[1];
  718.                } else if (var26[1].getParameterTypes().length == 0) {
  719.                   var12 = var26[0];
  720.                }
  721.             }
  722.  
  723.             if (var12 == null) {
  724.                Object[] var31 = new Object[]{var1.getName()};
  725.                throw new ClassDefinitionException(Context.getMessage("msg.ctor.multiple.parms", var31));
  726.             }
  727.          }
  728.  
  729.          FunctionObject var30 = new FunctionObject(var7, (Member)var12, var0);
  730.          var30.addAsConstructor(var0, var28);
  731.          Method var32 = null;
  732.  
  733.          for(int var33 = 0; var33 < var2.length; ++var33) {
  734.             if (var2[var33].getDeclaringClass() == var1) {
  735.                String var35 = var2[var33].getName();
  736.                if (var35.equals("finishInit")) {
  737.                   Class[] var17 = var2[var33].getParameterTypes();
  738.                   if (var17.length == 3 && var17[0] == ScriptRuntime.ScriptableClass && var17[1] == (class$com$netscape$javascript$FunctionObject != null ? class$com$netscape$javascript$FunctionObject : (class$com$netscape$javascript$FunctionObject = class$("com.netscape.javascript.FunctionObject"))) && var17[2] == ScriptRuntime.ScriptableClass && Modifier.isStatic(var2[var33].getModifiers())) {
  739.                      var32 = var2[var33];
  740.                      continue;
  741.                   }
  742.                }
  743.  
  744.                String var36 = null;
  745.                if (var11) {
  746.                   if (var35.startsWith("js_")) {
  747.                      var35 = var35.substring("js_".length());
  748.                      var36 = "js_";
  749.                   } else if (var35.startsWith("jsFunction_")) {
  750.                      var35 = var35.substring("jsFunction_".length());
  751.                      var36 = "jsFunction_";
  752.                   } else {
  753.                      if (!var35.startsWith("jsProperty_")) {
  754.                         continue;
  755.                      }
  756.  
  757.                      var35 = var35.substring("jsProperty_".length());
  758.                      var36 = "jsProperty_";
  759.                   }
  760.                } else if (var25.get(var35) != null) {
  761.                   continue;
  762.                }
  763.  
  764.                if (var2[var33] != var12) {
  765.                   if ((var35.startsWith("get") || var35.startsWith("set")) && var35.length() > 3 && (!var11 || !var36.equals("jsFunction_"))) {
  766.                      if (!(var28 instanceof ScriptableObject)) {
  767.                         Object[] var38 = new Object[]{var28.getClass().toString(), var35};
  768.                         throw new PropertyException(Context.getMessage("msg.extend.scriptable", var38));
  769.                      }
  770.  
  771.                      if (!var35.startsWith("set")) {
  772.                         StringBuffer var37 = new StringBuffer();
  773.                         char var19 = var35.charAt(3);
  774.                         var37.append(Character.toLowerCase(var19));
  775.                         if (var35.length() > 4) {
  776.                            var37.append(var35.substring(4));
  777.                         }
  778.  
  779.                         String var20 = var37.toString();
  780.                         var37.setCharAt(0, var19);
  781.                         var37.insert(0, "set");
  782.                         String var21 = var37.toString();
  783.                         Method[] var22 = FunctionObject.findMethods(var1, var11 ? "js_" + var21 : var21);
  784.                         if (var22 != null && var22.length != 1) {
  785.                            Object[] var39 = new Object[]{var35, var1.getName()};
  786.                            throw new PropertyException(Context.getMessage("msg.no.overload", var39));
  787.                         }
  788.  
  789.                         if (var22 == null && var11) {
  790.                            var22 = FunctionObject.findMethods(var1, "jsProperty_" + var21);
  791.                         }
  792.  
  793.                         int var23 = 6 | (var22 != null ? 0 : 1);
  794.                         Method var24 = var22 == null ? null : var22[0];
  795.                         ((ScriptableObject)var28).defineProperty(var20, (Object)null, var2[var33], var24, var23);
  796.                      }
  797.                   } else {
  798.                      FunctionObject var18 = new FunctionObject(var35, var2[var33], var28);
  799.                      if (var28 instanceof ScriptableObject) {
  800.                         ((ScriptableObject)var28).defineProperty(var35, (Object)var18, 2);
  801.                      } else {
  802.                         var28.put(var35, var28, var18);
  803.                      }
  804.                   }
  805.                }
  806.             }
  807.          }
  808.  
  809.          if (var32 != null) {
  810.             Object[] var34 = new Object[]{var0, var30, var28};
  811.             var32.invoke((Object)null, var34);
  812.          }
  813.  
  814.       }
  815.    }
  816.  
  817.    // $FF: synthetic method
  818.    private static Class class$(String var0) {
  819.       try {
  820.          return Class.forName(var0);
  821.       } catch (ClassNotFoundException var2) {
  822.          throw new NoClassDefFoundError(((Throwable)var2).getMessage());
  823.       }
  824.    }
  825.  
  826.    private synchronized void removeSlot(String var1, int var2) {
  827.       int var3 = this.getSlot(var1, var2);
  828.       if (var3 != -1) {
  829.          if ((this.slots[var3].attributes & 4) == 0) {
  830.             this.slots[var3] = REMOVED;
  831.             this.count += -1;
  832.          }
  833.       }
  834.    }
  835.  
  836.    private synchronized void grow() {
  837.       Slot[] var1 = new Slot[this.slots.length * 2 + 1];
  838.  
  839.       for(int var2 = this.slots.length - 1; var2 >= 0; --var2) {
  840.          Slot var3 = this.slots[var2];
  841.          if (var3 != null && var3 != REMOVED) {
  842.             int var4 = (var3.intKey & Integer.MAX_VALUE) % var1.length;
  843.  
  844.             while(var1[var4] != null) {
  845.                ++var4;
  846.                if (var4 == var1.length) {
  847.                   var4 = 0;
  848.                }
  849.             }
  850.  
  851.             synchronized(var3){}
  852.             var1[var4] = var3;
  853.          }
  854.       }
  855.  
  856.       this.slots = var1;
  857.    }
  858.  
  859.    public void delete(String var1) {
  860.       if (var1.equals(this.lastName)) {
  861.          this.lastValue = REMOVED;
  862.       }
  863.  
  864.       this.removeSlot(var1, var1.hashCode());
  865.    }
  866.  
  867.    public void delete(int var1) {
  868.       this.removeSlot((String)null, var1);
  869.    }
  870.  
  871.    public static Scriptable getTopLevelScope(Scriptable var0) {
  872.       Scriptable var1 = var0;
  873.  
  874.       do {
  875.          var0 = var1;
  876.          var1 = var1.getParentScope();
  877.       } while(var1 != null);
  878.  
  879.       return var0;
  880.    }
  881. }
  882.