示例#1
0
  public ExecutionContext createFunctionExecutionContext(
      Object functionReference, JSFunction function, Object thisArg, Object... arguments) {
    // 10.4.3
    Object thisBinding = null;
    if (function.isStrict()) {
      thisBinding = thisArg;
    } else {
      if (thisArg == null || thisArg == Types.NULL || thisArg == Types.UNDEFINED) {
        thisBinding = this.getLexicalEnvironment().getGlobalObject();
      } else if (!(thisArg instanceof JSObject)) {
        // thisBinding = Types.toObject(this, thisArg);
        thisBinding = Types.toThisObject(this, thisArg);
      } else {
        thisBinding = thisArg;
      }
    }

    LexicalEnvironment scope = function.getScope();
    LexicalEnvironment localEnv = LexicalEnvironment.newDeclarativeEnvironment(scope);

    ExecutionContext context =
        new ExecutionContext(this, localEnv, localEnv, thisBinding, function.isStrict());
    context.performDeclarationBindingInstantiation(function, arguments);
    context.fileName = function.getFileName();
    // System.err.println( "debug null: " + ( function.getDebugContext() == null ? function : "not
    // null") );
    context.debugContext = function.getDebugContext();
    context.functionReference = functionReference;
    return context;
  }
示例#2
0
  private void performDeclarationBindingInstantiation(JSFunction function, Object[] arguments) {
    // 10.5 (Functions)
    String[] names = function.getFormalParameters();

    Object v = null;

    DeclarativeEnvironmentRecord env =
        (DeclarativeEnvironmentRecord) this.variableEnvironment.getRecord();

    // * 4
    for (int i = 0; i < names.length; ++i) {
      if ((i + 1) > arguments.length) {
        v = Types.UNDEFINED;
      } else {
        v = arguments[i];
      }

      if (!env.hasBinding(this, names[i])) {
        env.createMutableBinding(this, names[i], false);
      }

      env.setMutableBinding(this, names[i], v, function.isStrict());
    }

    // * 5
    performFunctionDeclarationBindings(function, false);

    // * 6
    if (!env.hasBinding(this, "arguments")) {
      // * 7
      Arguments argsObj = createArgumentsObject(function, arguments);

      if (function.isStrict()) {
        env.createImmutableBinding("arguments");
        env.initializeImmutableBinding("arguments", argsObj);
      } else {
        env.createMutableBinding(this, "arguments", false);
        env.setMutableBinding(this, "arguments", argsObj, false);
      }
    }

    // * 8
    performVariableDeclarationBindings(function, false);
  }
示例#3
0
  private Arguments createArgumentsObject(final JSFunction function, final Object[] arguments) {
    // 10.6

    Arguments obj = new Arguments(getGlobalObject());
    PropertyDescriptor desc =
        new PropertyDescriptor() {
          {
            set("Value", arguments.length);
            set("Writable", true);
            set("Enumerable", false);
            set("Configurable", true);
          }
        };
    obj.defineOwnProperty(this, "length", desc, false);

    String[] names = function.getFormalParameters();

    JSObject map = new DynObject(getGlobalObject());
    List<String> mappedNames = new ArrayList<>();

    final LexicalEnvironment env = getVariableEnvironment();

    for (int i = 0; i < arguments.length; ++i) {
      final Object val = arguments[i];
      desc =
          new PropertyDescriptor() {
            {
              set("Value", val);
              set("Writable", true);
              set("Enumerable", true);
              set("Configurable", true);
            }
          };

      obj.defineOwnProperty(this, "" + i, desc, false);

      if (i < names.length) {
        if (!function.isStrict()) {
          final String name = names[i];
          if (i < names.length) {
            if (!mappedNames.contains(name)) {
              mappedNames.add(name);

              desc =
                  new PropertyDescriptor() {
                    {
                      set("Set", new ArgSetter(env, name));
                      set("Get", new ArgGetter(env, name));
                      set("Configurable", true);
                    }
                  };
              map.defineOwnProperty(this, "" + i, desc, false);
            }
          }
        }
      }
    }

    if (!mappedNames.isEmpty()) {
      obj.setParameterMap(map);
    }

    if (function.isStrict()) {
      final JSFunction thrower = (JSFunction) getGlobalObject().get(this, "__throwTypeError");

      obj.defineOwnProperty(
          this,
          "caller",
          new PropertyDescriptor() {
            {
              set("Get", thrower);
              set("Set", thrower);
              set("Enumerable", false);
              set("Configurable", false);
            }
          },
          false);

      obj.defineOwnProperty(
          this,
          "callee",
          new PropertyDescriptor() {
            {
              set("Get", thrower);
              set("Set", thrower);
              set("Enumerable", false);
              set("Configurable", false);
            }
          },
          false);

    } else {
      obj.defineOwnProperty(
          this,
          "callee",
          new PropertyDescriptor() {
            {
              set("Value", function);
              set("Writable", true);
              set("Enumerable", false);
              set("Configurable", true);
            }
          },
          false);
    }

    return obj;
  }