Search in sources :

Example 26 with ScriptObject

use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.

the class FunctionCodeGenerator method generateLegacyFunctionConstruct.

/**
     * Generate bytecode for:
     * 
     * <pre>
     * oldCaller = function.getLegacyCaller()
     * oldArguments = function.getLegacyArguments()
     * function.setLegacyCaller(callerContext.getCurrentFunction())
     * try {
     *   thisArgument = OrdinaryCreateFromConstructor(callerContext, newTarget, %ObjectPrototype%)
     *   calleeContext = newFunctionExecutionContext(function, newTarget, thisArgument)
     *   result = OrdinaryCallEvaluateBody(function, argumentsList)
     *   return returnResultOrThis(result)
     * } finally {
     *   function.restoreLegacyProperties(oldCaller, oldArguments)
     * }
     * </pre>
     * 
     * @param node
     *            the function node
     * @param mv
     *            the instruction visitor
     */
private void generateLegacyFunctionConstruct(FunctionNode node, InstructionVisitor mv) {
    final boolean hasArguments = codegen.isEnabled(CompatibilityOption.FunctionArguments);
    final boolean hasCaller = codegen.isEnabled(CompatibilityOption.FunctionCaller);
    Variable<LegacyConstructorFunction> function = mv.getParameter(FUNCTION, LegacyConstructorFunction.class);
    Variable<ExecutionContext> callerContext = mv.getParameter(EXECUTION_CONTEXT, ExecutionContext.class);
    Variable<Constructor> newTarget = mv.getParameter(NEW_TARGET, Constructor.class);
    Variable<Object[]> arguments = mv.getParameter(ARGUMENTS, Object[].class);
    Variable<ScriptObject> thisArg = mv.newVariable("thisArgument", ScriptObject.class);
    Variable<ExecutionContext> calleeContext = mv.newVariable("calleeContext", ExecutionContext.class);
    Variable<FunctionObject> oldCaller = mv.newVariable("oldCaller", FunctionObject.class);
    Variable<LegacyConstructorFunction.Arguments> oldArguments = mv.newVariable("oldArguments", LegacyConstructorFunction.Arguments.class);
    Variable<Throwable> throwable = mv.newVariable("throwable", Throwable.class);
    // (1) Retrieve 'caller' and 'arguments' and store in local variables
    if (hasCaller) {
        mv.load(function);
        mv.invoke(Methods.LegacyConstructorFunction_getLegacyCaller);
    } else {
        mv.anull();
    }
    mv.store(oldCaller);
    if (hasArguments) {
        mv.load(function);
        mv.invoke(Methods.LegacyConstructorFunction_getLegacyArguments);
    } else {
        mv.anull();
    }
    mv.store(oldArguments);
    // (2) Update 'caller' and 'arguments' properties
    if (hasCaller) {
        setLegacyCaller(function, callerContext, mv);
    }
    if (hasArguments) {
        setLegacyArguments(function, arguments, mv);
    }
    TryCatchLabel startFinally = new TryCatchLabel(), endFinally = new TryCatchLabel();
    TryCatchLabel handlerFinally = new TryCatchLabel();
    mv.mark(startFinally);
    {
        // (3) Create this-argument
        ordinaryCreateFromConstructor(callerContext, newTarget, thisArg, mv);
        // (4) Create a new ExecutionContext
        prepareCallAndBindThis(node, calleeContext, function, newTarget, thisArg, mv);
        // (5) Call OrdinaryCallEvaluateBody
        ordinaryCallEvaluateBody(node, calleeContext, function, arguments, mv);
        // (6) Restore 'caller' and 'arguments'
        restoreLegacyProperties(function, oldCaller, oldArguments, mv);
        // (7) Return result value
        returnResultOrThis(thisArg, false, mv);
    }
    mv.mark(endFinally);
    // Exception: Restore 'caller' and 'arguments' and then rethrow exception
    mv.finallyHandler(handlerFinally);
    mv.store(throwable);
    restoreLegacyProperties(function, oldCaller, oldArguments, mv);
    mv.load(throwable);
    mv.athrow();
    mv.tryFinally(startFinally, endFinally, handlerFinally);
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) Constructor(com.github.anba.es6draft.runtime.types.Constructor) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) ExecutionContext(com.github.anba.es6draft.runtime.ExecutionContext) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Example 27 with ScriptObject

use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.

the class SourceBuilder method source.

private String source(ExecutionContext cx, HashSet<ScriptObject> stack, Object value) {
    switch(Type.of(value)) {
        case Null:
            return "null";
        case Boolean:
            return Type.booleanValue(value) ? "true" : "false";
        case String:
            return Strings.quote(Type.stringValue(value).toString());
        case Symbol:
            return Type.symbolValue(value).toString();
        case Number:
            return ToFlatString(cx, value);
        case SIMD:
            return Type.simdValue(value).toString();
        case Object:
            ScriptObject objValue = Type.objectValue(value);
            if (IsCallable(objValue)) {
                return ((Callable) objValue).toSource(cx);
            }
            if (stack.contains(objValue) || stack.size() > maxStackDepth) {
                return "« ... »";
            }
            stack.add(objValue);
            try {
                if (objValue instanceof DateObject) {
                    return DatePrototype.Properties.toString(cx, value).toString();
                } else if (objValue instanceof RegExpObject) {
                    return RegExpPrototype.Properties.toString(cx, value).toString();
                } else if (objValue instanceof ArrayObject) {
                    return arrayToSource(cx, stack, objValue);
                } else {
                    return objectToSource(cx, stack, objValue);
                }
            } finally {
                stack.remove(objValue);
            }
        case Undefined:
        default:
            return "(void 0)";
    }
}
Also used : ArrayObject(com.github.anba.es6draft.runtime.types.builtins.ArrayObject) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) RegExpObject(com.github.anba.es6draft.runtime.objects.text.RegExpObject) IsCallable(com.github.anba.es6draft.runtime.AbstractOperations.IsCallable) Callable(com.github.anba.es6draft.runtime.types.Callable) DateObject(com.github.anba.es6draft.runtime.objects.date.DateObject)

Example 28 with ScriptObject

use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.

the class SourceBuilder method objectToSource.

private String objectToSource(ExecutionContext cx, HashSet<ScriptObject> stack, ScriptObject object) {
    Iterator<?> keys = object.ownKeys(cx);
    if (!keys.hasNext()) {
        return "{}";
    }
    StringBuilder properties = new StringBuilder();
    for (int i = 0; keys.hasNext() && i < maxObjectProperties; ) {
        Object k = keys.next();
        String key = propertyKeyToSource(cx, k);
        Property prop;
        try {
            prop = object.getOwnProperty(cx, k);
        } catch (ScriptException e) {
            continue;
        }
        if (!prop.isEnumerable()) {
            continue;
        }
        String value;
        if (prop.isDataDescriptor()) {
            value = toSource(cx, stack, prop.getValue());
        } else {
            value = accessorToSource(prop);
        }
        properties.append(", ").append(key).append(": ").append(value);
        i += 1;
    }
    if (keys.hasNext()) {
        properties.append(", [...]");
    }
    properties.append(" }").setCharAt(0, '{');
    return properties.toString();
}
Also used : ScriptException(com.github.anba.es6draft.runtime.internal.ScriptException) DateObject(com.github.anba.es6draft.runtime.objects.date.DateObject) RegExpObject(com.github.anba.es6draft.runtime.objects.text.RegExpObject) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) ArrayObject(com.github.anba.es6draft.runtime.types.builtins.ArrayObject) ToFlatString(com.github.anba.es6draft.runtime.AbstractOperations.ToFlatString) Property(com.github.anba.es6draft.runtime.types.Property)

Example 29 with ScriptObject

use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.

the class StatementGenerator method AsyncForInOfBodyEvaluation.

/**
     * 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation (lhs, stmt, iterator, lhsKind, labelSet)
     * <p>
     * stack: [Iterator] {@literal ->} []
     * 
     * @param <FORSTATEMENT>
     *            the for-statement node type
     * @param node
     *            the for-statement node
     * @param mv
     *            the code visitor
     * @return the completion value
     */
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion AsyncForInOfBodyEvaluation(FORSTATEMENT node, CodeVisitor mv) {
    assert mv.getStackSize() == 1;
    ContinueLabel lblContinue = new ContinueLabel();
    BreakLabel lblBreak = new BreakLabel();
    Jump enter = new Jump(), test = new Jump();
    mv.enterVariableScope();
    Variable<ScriptObject> iterator = mv.newVariable("iter", ScriptObject.class);
    // stack: [Iterator] -> []
    mv.store(iterator);
    Variable<ScriptObject> nextResult = mv.newVariable("nextResult", ScriptObject.class);
    mv.anull();
    mv.store(nextResult);
    Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
    mv.anull();
    mv.store(nextValue);
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
    /* step 2 */
    if (node.hasCompletionValue()) {
        mv.storeUndefinedAsCompletionValue();
    }
    /* steps 3-4 (not applicable) */
    /* step 5 (repeat loop) */
    mv.nonDestructiveGoTo(test);
    /* steps 5.d-e */
    mv.mark(enter);
    IteratorValue(node, nextResult, mv);
    await(node, mv);
    mv.store(nextValue);
    /* steps 5.f-l */
    {
        mv.enterIteration(node, lblBreak, lblContinue);
        mv.enterWrapped();
        new AbstractIterationGenerator<FORSTATEMENT, ScriptObject>(codegen) {

            @Override
            protected Completion iterationBody(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
                return ForInOfBodyEvaluationInner(node, nextValue, mv);
            }

            @Override
            protected MutableValue<Object> enterIteration(FORSTATEMENT node, CodeVisitor mv) {
                return mv.enterIterationBody(node);
            }

            @Override
            protected List<TempLabel> exitIteration(FORSTATEMENT node, CodeVisitor mv) {
                return mv.exitIterationBody(node);
            }

            @Override
            protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, Variable<? extends Throwable> throwable, CodeVisitor mv) {
                asyncIteratorClose(node, iterator, throwable, mv);
            }

            @Override
            protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
                asyncIteratorClose(node, iterator, mv);
            }
        }.generate(node, iterator, test, mv);
        mv.exitWrapped();
        mv.exitIteration(node);
    }
    /* steps 5.m-n */
    if (lblContinue.isTarget()) {
        mv.mark(lblContinue);
        restoreEnvironment(savedEnv, mv);
    }
    /* steps 5.a-c */
    mv.mark(test);
    IteratorNext(node, iterator, mv);
    await(node, mv);
    // FIXME: spec bug - missing type check after await
    requireObjectResult(node, "next", mv);
    mv.store(nextResult);
    IteratorComplete(node, nextResult, mv);
    mv.ifeq(enter);
    /* steps 5.m-n */
    if (lblBreak.isTarget()) {
        mv.mark(lblBreak);
        restoreEnvironment(savedEnv, mv);
    }
    mv.exitVariableScope();
    return Completion.Normal;
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) Variable(com.github.anba.es6draft.compiler.assembler.Variable) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel) ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel)

Example 30 with ScriptObject

use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.

the class MozShellFunctions method evalcx.

/**
     * shell-function: {@code evalcx(s, [o])}
     *
     * @param cx
     *            the execution context
     * @param caller
     *            the caller context
     * @param sourceCode
     *            the source to evaluate
     * @param o
     *            the global object
     * @return the eval result value
     */
@Function(name = "evalcx", arity = 1)
public Object evalcx(ExecutionContext cx, ExecutionContext caller, String sourceCode, Object o) {
    ScriptObject global;
    if (Type.isUndefinedOrNull(o)) {
        global = newGlobal(cx);
    } else {
        global = ToObject(cx, o);
    }
    if (sourceCode.isEmpty() || "lazy".equals(sourceCode)) {
        return global;
    }
    if (!(global instanceof GlobalObject)) {
        throw Errors.newError(cx, "invalid global argument");
    }
    Source source = new Source(cx.getRealm().sourceInfo(caller), "evalcx", 1);
    Realm realm = ((GlobalObject) global).getRealm();
    try {
        Script script = realm.getScriptLoader().script(source, sourceCode);
        return script.evaluate(realm);
    } catch (ParserException | CompilationException e) {
        // Create a script exception from the requested code realm, not from the caller's realm.
        throw e.toScriptException(realm.defaultContext());
    }
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) GlobalObject(com.github.anba.es6draft.runtime.objects.GlobalObject) SharedFunctions.relativePathToScript(com.github.anba.es6draft.repl.global.SharedFunctions.relativePathToScript) Script(com.github.anba.es6draft.Script) SharedFunctions.loadScript(com.github.anba.es6draft.repl.global.SharedFunctions.loadScript) ParserException(com.github.anba.es6draft.parser.ParserException) CompilationException(com.github.anba.es6draft.compiler.CompilationException) Realm(com.github.anba.es6draft.runtime.Realm) ToSource(com.github.anba.es6draft.repl.SourceBuilder.ToSource) Source(com.github.anba.es6draft.runtime.internal.Source) Function(com.github.anba.es6draft.runtime.internal.Properties.Function) BuiltinFunction(com.github.anba.es6draft.runtime.types.builtins.BuiltinFunction)

Aggregations

ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)129 Callable (com.github.anba.es6draft.runtime.types.Callable)43 Property (com.github.anba.es6draft.runtime.types.Property)32 OrdinaryObject (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject)26 ArrayObject (com.github.anba.es6draft.runtime.types.builtins.ArrayObject)21 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)16 Constructor (com.github.anba.es6draft.runtime.types.Constructor)11 Realm (com.github.anba.es6draft.runtime.Realm)9 PropertyDescriptor (com.github.anba.es6draft.runtime.types.PropertyDescriptor)9 ParserException (com.github.anba.es6draft.parser.ParserException)8 CompilationException (com.github.anba.es6draft.compiler.CompilationException)7 Source (com.github.anba.es6draft.runtime.internal.Source)7 ArrayList (java.util.ArrayList)7 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)6 ImmutablePrototypeObject (com.github.anba.es6draft.runtime.types.builtins.ImmutablePrototypeObject)6 OrdinaryCreateFromConstructor (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject.OrdinaryCreateFromConstructor)6 Test (org.junit.Test)6 GlobalEnvironmentRecord (com.github.anba.es6draft.runtime.GlobalEnvironmentRecord)5 IsCallable (com.github.anba.es6draft.runtime.AbstractOperations.IsCallable)4 RuntimeInfo (com.github.anba.es6draft.runtime.internal.RuntimeInfo)4