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

  1. package com.netscape.javascript;
  2.  
  3. import java.util.Hashtable;
  4.  
  5. public class NativeFunction extends RescopeableObject implements Function {
  6.    private static final int OFFSET = 4;
  7.    private static final int SETBACK = 2;
  8.    private static final boolean printSource = false;
  9.    protected String[] names;
  10.    protected short argCount;
  11.    protected short version;
  12.    protected String source;
  13.    public NativeFunction[] nestedFunctions;
  14.    public int debug_level = -1;
  15.    public String debug_srcName;
  16.  
  17.    public String decompile(int var1, boolean var2, boolean var3) {
  18.       if (this.source == null) {
  19.          return "function " + this.js_getName() + "() {\n\t[native code]\n}\n";
  20.       } else {
  21.          StringBuffer var4 = new StringBuffer();
  22.          int var5 = 0;
  23.          if (this.source.length() > 0) {
  24.             if (var2) {
  25.                if (!var3) {
  26.                   var4.append('\n');
  27.                }
  28.  
  29.                for(int var6 = 0; var6 < var1; ++var6) {
  30.                   var4.append(' ');
  31.                }
  32.             }
  33.  
  34.             if (this.source.charAt(0) == 'm' && this.source.length() > 1 && (this.source.charAt(1) == ',' || this.source.charAt(1) == ']')) {
  35.                if (!var3) {
  36.                   var4.append("function ");
  37.                   if (this.nextIs(var5, 93) && this.version != 120 && this.names != null && this.names[0].length() == 0) {
  38.                      var4.append("anonymous");
  39.                   }
  40.  
  41.                   ++var5;
  42.                } else {
  43.                   while(var5 < this.source.length() && (this.source.charAt(var5) != 1 || var5 > 0 && this.source.charAt(var5 - 1) == ',')) {
  44.                      ++var5;
  45.                   }
  46.  
  47.                   ++var5;
  48.                }
  49.             }
  50.          }
  51.  
  52.          for(; var5 < this.source.length(); ++var5) {
  53.             switch (this.source.charAt(var5)) {
  54.                case '\u0001':
  55.                   var4.append('\n');
  56.                   if (var5 + 1 < this.source.length()) {
  57.                      int var31 = 0;
  58.                      if (!this.nextIs(var5, 115) && !this.nextIs(var5, 116)) {
  59.                         if (this.nextIs(var5, 92)) {
  60.                            var31 = 4;
  61.                         } else if (this.nextIs(var5, 44)) {
  62.                            char var32 = this.source.charAt(var5 + 2);
  63.                            if (this.source.charAt(var5 + var32 + 3) == 'b') {
  64.                               var31 = 4;
  65.                            }
  66.                         }
  67.                      } else {
  68.                         var31 = 2;
  69.                      }
  70.  
  71.                      while(var31 < var1) {
  72.                         var4.append(' ');
  73.                         ++var31;
  74.                      }
  75.                   }
  76.                   break;
  77.                case '\u0005':
  78.                   if (this.nextIs(var5, 88)) {
  79.                      var4.append("return");
  80.                   } else {
  81.                      var4.append("return ");
  82.                   }
  83.                   break;
  84.                case '\u000b':
  85.                   var4.append(" | ");
  86.                   break;
  87.                case '\f':
  88.                   var4.append(" ^ ");
  89.                   break;
  90.                case '\r':
  91.                   var4.append(" & ");
  92.                   break;
  93.                case '\u0017':
  94.                   var4.append(" + ");
  95.                   break;
  96.                case '\u0018':
  97.                   var4.append(" - ");
  98.                   break;
  99.                case '\u0019':
  100.                   var4.append(" * ");
  101.                   break;
  102.                case '\u001a':
  103.                   var4.append(" / ");
  104.                   break;
  105.                case '\u001b':
  106.                   var4.append(" % ");
  107.                   break;
  108.                case '\u001e':
  109.                   var4.append("new ");
  110.                   break;
  111.                case '\u001f':
  112.                   var4.append("delete ");
  113.                   break;
  114.                case ',':
  115.                case '8':
  116.                   ++var5;
  117.                   int var21 = var5 + this.source.charAt(var5);
  118.                   var4.append(this.source.substring(var5 + 1, var21 + 1));
  119.                   var5 = var21;
  120.                   break;
  121.                case '-':
  122.                   ++var5;
  123.                   long var7 = 0L;
  124.                   switch (this.source.charAt(var5)) {
  125.                      case 'D':
  126.                         ++var5;
  127.                         var7 |= (long)this.source.charAt(var5++) << 48;
  128.                         var7 |= (long)this.source.charAt(var5++) << 32;
  129.                         var7 |= (long)this.source.charAt(var5++) << 16;
  130.                         var7 |= (long)this.source.charAt(var5);
  131.                         double var30 = Double.longBitsToDouble(var7);
  132.                         var4.append(ScriptRuntime.numberToString(var30));
  133.                         continue;
  134.                      case 'J':
  135.                         ++var5;
  136.                         var7 |= (long)this.source.charAt(var5++) << 48;
  137.                         var7 |= (long)this.source.charAt(var5++) << 32;
  138.                         var7 |= (long)this.source.charAt(var5++) << 16;
  139.                         var7 |= (long)this.source.charAt(var5);
  140.                         var4.append(var7);
  141.                         continue;
  142.                      case 'S':
  143.                         ++var5;
  144.                         var4.append(this.source.charAt(var5));
  145.                      default:
  146.                         continue;
  147.                   }
  148.                case '.':
  149.                   ++var5;
  150.                   int var20 = var5 + this.source.charAt(var5);
  151.                   var4.append('"');
  152.                   var4.append(ScriptRuntime.escapeString(this.source.substring(var5 + 1, var20 + 1)));
  153.                   var4.append('"');
  154.                   var5 = var20;
  155.                   break;
  156.                case '>':
  157.                   var4.append("throw ");
  158.                   break;
  159.                case '?':
  160.                   var4.append(" in ");
  161.                   break;
  162.                case 'K':
  163.                   var4.append("try ");
  164.                   break;
  165.                case 'X':
  166.                   if (this.nextIs(var5, 1)) {
  167.                      var4.append(";");
  168.                   } else {
  169.                      var4.append("; ");
  170.                   }
  171.                   break;
  172.                case 'Y':
  173.                   var4.append('[');
  174.                   break;
  175.                case 'Z':
  176.                   var4.append(']');
  177.                   break;
  178.                case '[':
  179.                   if (this.nextIs(var5, 1)) {
  180.                      var1 += 4;
  181.                   }
  182.  
  183.                   var4.append("{");
  184.                   break;
  185.                case '\\':
  186.                   if (!var3 || !var2 || var5 + 1 != this.source.length()) {
  187.                      if (this.nextIs(var5, 1)) {
  188.                         var1 -= 4;
  189.                      }
  190.  
  191.                      if (!this.nextIs(var5, 117) && !this.nextIs(var5, 113)) {
  192.                         var4.append('}');
  193.                      } else {
  194.                         var1 -= 4;
  195.                         var4.append("} ");
  196.                      }
  197.                   }
  198.                   break;
  199.                case ']':
  200.                   var4.append('(');
  201.                   break;
  202.                case '^':
  203.                   if (this.nextIs(var5, 91)) {
  204.                      var4.append(") ");
  205.                   } else {
  206.                      var4.append(')');
  207.                   }
  208.                   break;
  209.                case '_':
  210.                   var4.append(", ");
  211.                   break;
  212.                case '`':
  213.                   ++var5;
  214.                   switch (this.source.charAt(var5)) {
  215.                      case '\u000b':
  216.                         var4.append(" |= ");
  217.                         continue;
  218.                      case '\f':
  219.                         var4.append(" ^= ");
  220.                         continue;
  221.                      case '\r':
  222.                         var4.append(" &= ");
  223.                         continue;
  224.                      case '\u0014':
  225.                         var4.append(" <<= ");
  226.                         continue;
  227.                      case '\u0015':
  228.                         var4.append(" >>= ");
  229.                         continue;
  230.                      case '\u0016':
  231.                         var4.append(" >>>= ");
  232.                         continue;
  233.                      case '\u0017':
  234.                         var4.append(" += ");
  235.                         continue;
  236.                      case '\u0018':
  237.                         var4.append(" -= ");
  238.                         continue;
  239.                      case '\u0019':
  240.                         var4.append(" *= ");
  241.                         continue;
  242.                      case '\u001a':
  243.                         var4.append(" /= ");
  244.                         continue;
  245.                      case '\u001b':
  246.                         var4.append(" %= ");
  247.                         continue;
  248.                      case '\u007f':
  249.                         var4.append(" = ");
  250.                      default:
  251.                         continue;
  252.                   }
  253.                case 'a':
  254.                   var4.append(" ? ");
  255.                   break;
  256.                case 'b':
  257.                   if (this.nextIs(var5, 1)) {
  258.                      var4.append(":");
  259.                   } else {
  260.                      var4.append(" : ");
  261.                   }
  262.                   break;
  263.                case 'c':
  264.                   var4.append(" || ");
  265.                   break;
  266.                case 'd':
  267.                   var4.append(" && ");
  268.                   break;
  269.                case 'e':
  270.                   ++var5;
  271.                   switch (this.source.charAt(var5)) {
  272.                      case '\u000e':
  273.                         var4.append(" == ");
  274.                         continue;
  275.                      case '\u000f':
  276.                         var4.append(" != ");
  277.                         continue;
  278.                      case '5':
  279.                         var4.append(this.version == 120 ? " == " : " === ");
  280.                         continue;
  281.                      case '6':
  282.                         var4.append(this.version == 120 ? " != " : " !== ");
  283.                      default:
  284.                         continue;
  285.                   }
  286.                case 'f':
  287.                   ++var5;
  288.                   switch (this.source.charAt(var5)) {
  289.                      case '\u0010':
  290.                         var4.append(" < ");
  291.                         continue;
  292.                      case '\u0011':
  293.                         var4.append(" <= ");
  294.                         continue;
  295.                      case '\u0012':
  296.                         var4.append(" > ");
  297.                         continue;
  298.                      case '\u0013':
  299.                         var4.append(" >= ");
  300.                         continue;
  301.                      case '@':
  302.                         var4.append(" instanceof ");
  303.                      default:
  304.                         continue;
  305.                   }
  306.                case 'g':
  307.                   ++var5;
  308.                   switch (this.source.charAt(var5)) {
  309.                      case '\u0014':
  310.                         var4.append(" << ");
  311.                         continue;
  312.                      case '\u0015':
  313.                         var4.append(" >> ");
  314.                         continue;
  315.                      case '\u0016':
  316.                         var4.append(" >>> ");
  317.                      default:
  318.                         continue;
  319.                   }
  320.                case 'h':
  321.                   ++var5;
  322.                   switch (this.source.charAt(var5)) {
  323.                      case '\u0017':
  324.                         var4.append('+');
  325.                         continue;
  326.                      case '\u0018':
  327.                         var4.append('-');
  328.                         continue;
  329.                      case '\u001c':
  330.                         var4.append('~');
  331.                         continue;
  332.                      case ' ':
  333.                         var4.append("typeof ");
  334.                         continue;
  335.                      case '\u0080':
  336.                         var4.append('!');
  337.                         continue;
  338.                      case '\u0083':
  339.                         var4.append("void ");
  340.                      default:
  341.                         continue;
  342.                   }
  343.                case 'i':
  344.                   var4.append("++");
  345.                   break;
  346.                case 'j':
  347.                   var4.append("--");
  348.                   break;
  349.                case 'k':
  350.                   var4.append('.');
  351.                   break;
  352.                case 'l':
  353.                   ++var5;
  354.                   switch (this.source.charAt(var5)) {
  355.                      case ' ':
  356.                         var4.append("typeof");
  357.                         continue;
  358.                      case '1':
  359.                         var4.append("null");
  360.                         continue;
  361.                      case '2':
  362.                         var4.append("this");
  363.                         continue;
  364.                      case '3':
  365.                         var4.append("false");
  366.                         continue;
  367.                      case '4':
  368.                         var4.append("true");
  369.                         continue;
  370.                      case 'J':
  371.                         var4.append("undefined");
  372.                         continue;
  373.                      case '\u0083':
  374.                         var4.append("void");
  375.                      default:
  376.                         continue;
  377.                   }
  378.                case 'm':
  379.                   ++var5;
  380.                   char var9 = this.source.charAt(var5);
  381.                   if (this.nestedFunctions != null && var9 <= this.nestedFunctions.length) {
  382.                      var4.append(this.nestedFunctions[var9].decompile(var1, false, false));
  383.                      break;
  384.                   }
  385.  
  386.                   String var10;
  387.                   if (this.names != null && this.names.length > 0 && this.names[0].length() > 0) {
  388.                      Object[] var33 = new Object[]{new Integer(this.source.charAt(var5)), this.names[0]};
  389.                      var10 = Context.getMessage("msg.no.function.ref.found.in", var33);
  390.                   } else {
  391.                      Object[] var11 = new Object[]{new Integer(this.source.charAt(var5))};
  392.                      var10 = Context.getMessage("msg.no.function.ref.found", var11);
  393.                   }
  394.  
  395.                   throw Context.reportRuntimeError(var10);
  396.                case 'p':
  397.                   var4.append("if ");
  398.                   break;
  399.                case 'q':
  400.                   var4.append("else ");
  401.                   break;
  402.                case 'r':
  403.                   var4.append("switch ");
  404.                   break;
  405.                case 's':
  406.                   var4.append("case ");
  407.                   break;
  408.                case 't':
  409.                   var4.append("default");
  410.                   break;
  411.                case 'u':
  412.                   var4.append("while ");
  413.                   break;
  414.                case 'v':
  415.                   var4.append("do ");
  416.                   break;
  417.                case 'w':
  418.                   var4.append("for ");
  419.                   break;
  420.                case 'x':
  421.                   if (this.nextIs(var5, 44)) {
  422.                      var4.append("break ");
  423.                   } else {
  424.                      var4.append("break");
  425.                   }
  426.                   break;
  427.                case 'y':
  428.                   if (this.nextIs(var5, 44)) {
  429.                      var4.append("continue ");
  430.                   } else {
  431.                      var4.append("continue");
  432.                   }
  433.                   break;
  434.                case 'z':
  435.                   var4.append("var ");
  436.                   break;
  437.                case '{':
  438.                   var4.append("with ");
  439.                   break;
  440.                case '|':
  441.                   var4.append("catch ");
  442.                   break;
  443.                case '}':
  444.                   var4.append("finally ");
  445.                   break;
  446.                case '\u0086':
  447.                   var4.append(':');
  448.                   break;
  449.                default:
  450.                   throw new RuntimeException("Unknown token " + this.source.charAt(var5));
  451.             }
  452.          }
  453.  
  454.          if (var2 && !var3) {
  455.             var4.append('\n');
  456.          }
  457.  
  458.          return var4.toString();
  459.       }
  460.    }
  461.  
  462.    public static Object js_call(Context var0, Scriptable var1, Object[] var2, Function var3) throws JavaScriptException {
  463.       Object var4 = var1.getDefaultValue(ScriptRuntime.FunctionClass);
  464.       if (var2.length == 0) {
  465.          Scriptable var7 = ScriptRuntime.toObject(var3, var4);
  466.          return ScriptRuntime.call(var0, var4, var7.getParentScope(), ScriptRuntime.emptyArgs);
  467.       } else {
  468.          Scriptable var5 = var2[0] == null ? null : ScriptRuntime.toObject(var3, var2[0]);
  469.          Object[] var6 = new Object[var2.length - 1];
  470.          System.arraycopy(var2, 1, var6, 0, var6.length);
  471.          return ScriptRuntime.call(var0, var4, var5, var6);
  472.       }
  473.    }
  474.  
  475.    public String js_getName() {
  476.       if (this.names != null && this.names[0].length() > 0) {
  477.          return this.names[0];
  478.       } else {
  479.          Context var1 = Context.getCurrentContext();
  480.          return var1 != null && var1.getLanguageVersion() == 120 ? "" : "anonymous";
  481.       }
  482.    }
  483.  
  484.    public Scriptable construct(Context var1, Scriptable var2, Object[] var3) throws JavaScriptException {
  485.       NativeObject var4 = new NativeObject();
  486.       var4.setPrototype(this.getClassPrototype());
  487.       var4.setParentScope(((ScriptableObject)this).getParentScope());
  488.       Object var5 = this.call(var1, var2, var4, var3);
  489.       return (Scriptable)(var5 != null && var5 != Undefined.instance && var5 instanceof Scriptable ? (Scriptable)var5 : var4);
  490.    }
  491.  
  492.    public boolean hasInstance(Scriptable var1) {
  493.       FlattenedObject var2 = new FlattenedObject(this);
  494.       Object var3 = var2.getProperty("prototype");
  495.  
  496.       try {
  497.          var6 = ((FlattenedObject)var3).getObject();
  498.       } catch (ClassCastException var5) {
  499.          Object[] var4 = new Object[]{this.names[0]};
  500.          throw Context.reportRuntimeError(Context.getMessage("msg.instanceof.bad.prototype", var4));
  501.       }
  502.  
  503.       return ScriptRuntime.jsDelegatesTo(var1, var6);
  504.    }
  505.  
  506.    public int js_getArity() {
  507.       return this.argCount;
  508.    }
  509.  
  510.    private NativeCall getActivation(Context var1) {
  511.       for(NativeCall var2 = var1.currentActivation; var2 != null; var2 = var2.caller) {
  512.          if (var2.getFunctionObject() == this) {
  513.             return var2;
  514.          }
  515.       }
  516.  
  517.       return null;
  518.    }
  519.  
  520.    public Object get(String var1, Scriptable var2) {
  521.       Object var3 = super.get(var1, var2);
  522.       if (var3 != Scriptable.NOT_FOUND) {
  523.          return var3;
  524.       } else if (var1.equals("prototype")) {
  525.          NativeObject var6 = new NativeObject();
  526.          ((ScriptableObject)var6).setPrototype(ScriptableObject.getObjectPrototype(this));
  527.          boolean var5 = true;
  528.          ((ScriptableObject)var6).defineProperty("constructor", this, 7);
  529.          ((ScriptableObject)this).put(var1, this, var6);
  530.          return var6;
  531.       } else if (var1.equals("arguments")) {
  532.          NativeCall var4 = this.getActivation(Context.getContext());
  533.          return var4 == null ? null : ((ScriptableObject)var4).get("arguments", var4);
  534.       } else {
  535.          return Scriptable.NOT_FOUND;
  536.       }
  537.    }
  538.  
  539.    public int js_getLength() {
  540.       Context var1 = Context.getContext();
  541.       if (var1.getLanguageVersion() != 120) {
  542.          return this.argCount;
  543.       } else {
  544.          NativeCall var2 = this.getActivation(var1);
  545.          return var2 == null ? this.argCount : var2.getOriginalArguments().length;
  546.       }
  547.    }
  548.  
  549.    public static Object js_toString(Context var0, Scriptable var1, Object[] var2, Function var3) {
  550.       Object var4 = var1.getDefaultValue(ScriptRuntime.FunctionClass);
  551.       if (!(var4 instanceof NativeFunction)) {
  552.          Object[] var7 = new Object[]{"toString"};
  553.          String var6 = Context.getMessage("msg.incompat.call", var7);
  554.          throw Context.reportRuntimeError(var6);
  555.       } else {
  556.          int var5 = 0;
  557.          if (var2.length > 0) {
  558.             var5 = (int)ScriptRuntime.toNumber(var2[0]);
  559.          }
  560.  
  561.          return ((NativeFunction)var4).decompile(var5, true, false);
  562.       }
  563.    }
  564.  
  565.    protected Scriptable getClassPrototype() {
  566.       this.has("prototype", this);
  567.       Object var1 = this.get("prototype", this);
  568.       if (var1 == null || !(var1 instanceof Scriptable)) {
  569.          var1 = ScriptableObject.getClassPrototype(this, "Object");
  570.       }
  571.  
  572.       return (Scriptable)var1;
  573.    }
  574.  
  575.    public static void finishInit(Scriptable var0, FunctionObject var1, Scriptable var2) {
  576.       ((ScriptableObject)var1).setPrototype(var2);
  577.       String[] var3 = new String[]{""};
  578.       ((NativeFunction)var2).names = var3;
  579.    }
  580.  
  581.    private boolean nextIs(int var1, int var2) {
  582.       if (var1 + 1 < this.source.length()) {
  583.          return this.source.charAt(var1 + 1) == var2;
  584.       } else {
  585.          return false;
  586.       }
  587.    }
  588.  
  589.    public static Object js_apply(Context var0, Scriptable var1, Object[] var2, Function var3) throws JavaScriptException {
  590.       if (var2.length != 2) {
  591.          return js_call(var0, var1, var2, var3);
  592.       } else {
  593.          Object var4 = var1.getDefaultValue(ScriptRuntime.FunctionClass);
  594.          Scriptable var5 = var2[0] == null ? null : ScriptRuntime.toObject(var3, var2[0]);
  595.          Object[] var6 = var0.getElements((Scriptable)var2[1]);
  596.          return ScriptRuntime.call(var0, var4, var5, var6);
  597.       }
  598.    }
  599.  
  600.    public Object call(Context var1, Scriptable var2, Scriptable var3, Object[] var4) throws JavaScriptException {
  601.       return Undefined.instance;
  602.    }
  603.  
  604.    public synchronized Scriptable rescope(Hashtable var1) {
  605.       Scriptable var2 = (Scriptable)var1.get(this);
  606.       if (var2 != null) {
  607.          return var2;
  608.       } else {
  609.          NativeFunction var3 = (NativeFunction)super.rescope(var1);
  610.          if (this.nestedFunctions != null) {
  611.             var3.nestedFunctions = new NativeFunction[this.nestedFunctions.length];
  612.             RescopeableObject.rescopeArray(this.nestedFunctions, var3.nestedFunctions, var1);
  613.          }
  614.  
  615.          return var3;
  616.       }
  617.    }
  618.  
  619.    public static Scriptable js_Function(Context var0, Object[] var1, Function var2, boolean var3) {
  620.       int var4 = var1.length;
  621.       StringBuffer var5 = new StringBuffer();
  622.  
  623.       int var6;
  624.       for(var6 = 0; var6 < var4 - 1; ++var6) {
  625.          if (var6 > 0) {
  626.             var5.append(",");
  627.          }
  628.  
  629.          var5.append(ScriptRuntime.toString(var1[var6]));
  630.       }
  631.  
  632.       String var7 = var4 == 0 ? "" : ScriptRuntime.toString(var1[var6]);
  633.       String var8 = "function (" + var5.toString() + ") {" + var7 + "}";
  634.       int[] var9 = new int[1];
  635.       String var10 = Context.getSourcePositionFromStack(var9);
  636.       if (var10 == null) {
  637.          var10 = "<eval'ed string>";
  638.          var9[0] = 1;
  639.       }
  640.  
  641.       Object var11 = var0.getSecurityDomainForStackDepth(4);
  642.       Scriptable var12 = ScriptableObject.getTopLevelScope(var2);
  643.       int var13 = var0.getOptimizationLevel();
  644.       var0.setOptimizationLevel(-1);
  645.       NativeFunction var14 = (NativeFunction)var0.compileFunction(var12, var8, var10, var9[0], var11);
  646.       var0.setOptimizationLevel(var13);
  647.       if (var14.names == null) {
  648.          var14.names = new String[1];
  649.       }
  650.  
  651.       var14.names[0] = "";
  652.       ((ScriptableObject)var14).setPrototype(ScriptableObject.getFunctionPrototype(var12));
  653.       ((ScriptableObject)var14).setParentScope(var12);
  654.       return var14;
  655.    }
  656.  
  657.    public boolean has(String var1, Scriptable var2) {
  658.       return var1.equals("prototype") || var1.equals("arguments") || super.has(var1, var2);
  659.    }
  660.  
  661.    public String getClassName() {
  662.       return "Function";
  663.    }
  664. }
  665.