Search in sources :

Example 16 with ValType

use of com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType in project es6draft by anba.

the class ExpressionGenerator method visit.

/**
 * 12.2.9 Template Literals
 * <p>
 * 12.2.9.5 Runtime Semantics: Evaluation
 */
@Override
public ValType visit(TemplateLiteral node, CodeVisitor mv) {
    if (node.isTagged()) {
        MethodName method = mv.compile(node, this::templateLiteral);
        mv.iconst(codegen.templateKey(node));
        mv.handle(method);
        mv.loadExecutionContext();
        mv.invoke(Methods.TemplateOperations_GetTemplateObject);
        return ValType.Object;
    }
    List<Expression> elements = node.getElements();
    if (elements.size() == 1) {
        assert elements.get(0) instanceof TemplateCharacters;
        TemplateCharacters chars = (TemplateCharacters) elements.get(0);
        assert chars.getValue() != null;
        mv.aconst(chars.getValue());
    } else {
        // TODO: change to expression::concat?
        mv.anew(Methods.StringBuilder_new);
        for (Expression expr : elements) {
            if (expr instanceof TemplateCharacters) {
                String value = ((TemplateCharacters) expr).getValue();
                assert value != null;
                if (!value.isEmpty()) {
                    mv.aconst(value);
                    mv.invoke(Methods.StringBuilder_append_String);
                }
            } else {
                ValType type = expr.accept(this, mv);
                ToString(type, mv);
                mv.invoke(Methods.StringBuilder_append_Charsequence);
            }
        }
        mv.invoke(Methods.StringBuilder_toString);
    }
    return ValType.String;
}
Also used : MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) ValType(com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)

Example 17 with ValType

use of com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType in project es6draft by anba.

the class ExpressionGenerator method EvaluateCallValue.

private ValType EvaluateCallValue(Expression call, Expression base, List<Expression> arguments, CodeVisitor mv) {
    // stack: [] -> [func]
    ValType type = base.accept(this, mv);
    mv.toBoxed(type);
    /* steps 1-2 (not applicable) */
    // GetValue(...)
    /* steps 3-4 */
    // stack: [func] -> [func, cx, thisValue]
    mv.loadExecutionContext();
    mv.loadUndefined();
    // stack: [func, cx, thisValue] -> [result]
    return EvaluateDirectCall(call, arguments, mv);
}
Also used : ValType(com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)

Example 18 with ValType

use of com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType in project es6draft by anba.

the class ExpressionGenerator method visit.

/**
 * Extension: Async Function Definitions
 */
@Override
public ValType visit(AwaitExpression node, CodeVisitor mv) {
    ValType type = node.getExpression().accept(this, mv);
    mv.toBoxed(type);
    await(node, mv);
    return ValType.Any;
}
Also used : ValType(com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)

Example 19 with ValType

use of com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType in project es6draft by anba.

the class ExpressionGenerator method PerformEval.

/**
 * [18.2.1.1] Direct Call to Eval
 *
 * @param call
 *            the function call expression
 * @param arguments
 *            the list of function call arguments
 * @param hasThisValue
 *            {@code true} if the thisValue is on the stack
 * @param afterCall
 *            the label after the call instruction
 * @param mv
 *            the code visitor
 */
private void PerformEval(CallExpression call, List<Expression> arguments, boolean hasThisValue, Jump afterCall, CodeVisitor mv) {
    int evalFlags = EvalFlags.toFlags(call.getEvalFlags());
    if (mv.isStrict()) {
        // TODO: Remove this case when StrictDirectiveSimpleParameterList is the default.
        evalFlags |= EvalFlags.Strict.getValue();
    }
    if (isEnclosedByWithStatement(mv.getScope())) {
        evalFlags |= EvalFlags.EnclosedByWithStatement.getValue();
    }
    if (isEnclosedByCatchStatement(mv.getScope())) {
        evalFlags |= EvalFlags.EnclosedByCatchStatement.getValue();
    }
    if (!mv.isStrict() && isEnclosedByLexicalDeclaration(mv.getScope())) {
        evalFlags |= EvalFlags.EnclosedByLexicalDeclaration.getValue();
    }
    // stack: [thisValue?, args?, func(Callable)] -> [thisValue?, args?]
    mv.pop();
    // stack: [thisValue?, args?] -> [args?]
    boolean constantArguments = hasConstantArguments(arguments);
    if (hasThisValue) {
        if (constantArguments) {
            // stack: [thisValue] -> []
            mv.pop();
        } else {
            // stack: [thisValue, args] -> [args]
            mv.swap();
            mv.pop();
        }
    }
    if (codegen.isEnabled(CompatibilityOption.Realm)) {
        if (constantArguments) {
            // stack: [] -> [args]
            ArgumentListEvaluation(call, arguments, mv);
        }
        // stack: [args] -> [result]
        mv.loadExecutionContext();
        mv.iconst(evalFlags);
        mv.invoke(Methods.Eval_directEvalWithTranslate);
        mv.goTo(afterCall);
    } else {
        if (arguments.isEmpty()) {
            assert constantArguments : "empty arguments list is constant";
            // stack: [] -> [result]
            mv.loadUndefined();
            mv.goTo(afterCall);
        } else if (hasArguments(arguments)) {
            if (constantArguments) {
                // stack: [] -> [arg_0]
                ValType type = arguments.get(0).accept(this, mv);
                mv.toBoxed(type);
            } else {
                // stack: [args] -> [arg_0]
                mv.iconst(0);
                mv.aaload();
            }
            mv.loadExecutionContext();
            mv.iconst(evalFlags);
            mv.invoke(Methods.Eval_directEval);
            mv.goTo(afterCall);
        } else {
            assert !constantArguments : "spread arguments list is not constant";
            Jump emptyArguments = new Jump();
            mv.dup();
            mv.arraylength();
            mv.ifeq(emptyArguments);
            {
                mv.iconst(0);
                mv.aaload();
                mv.loadExecutionContext();
                mv.iconst(evalFlags);
                mv.invoke(Methods.Eval_directEval);
                mv.goTo(afterCall);
            }
            mv.mark(emptyArguments);
            mv.pop();
            mv.loadUndefined();
            mv.goTo(afterCall);
        }
    }
}
Also used : ValType(com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 20 with ValType

use of com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType in project es6draft by anba.

the class ExpressionGenerator method visit.

/**
 * 12.2.5 Array Initializer
 * <p>
 * 12.2.5.3 Runtime Semantics: Evaluation<br>
 * 12.2.5.2 Runtime Semantics: ArrayAccumulation
 */
@Override
public ValType visit(ArrayLiteral node, CodeVisitor mv) {
    int elision = 0, spread = 0;
    boolean hasSpreadMethod = false;
    for (Expression element : node.getElements()) {
        if (element instanceof SpreadElementMethod) {
            hasSpreadMethod = true;
            break;
        } else if (element instanceof Elision) {
            elision += 1;
        } else if (element instanceof SpreadElement) {
            spread += 1;
        }
    }
    if (hasSpreadMethod) {
        arrayLiteralWithSpread(node, mv);
    } else if (spread > 0 && hasTrailingSpread(node, spread)) {
        arrayLiteralTrailingSpread(node, mv);
    } else if (spread > 0) {
        arrayLiteralWithSpread(node, mv);
    } else {
        // Try to initialize array with faster {Dense, Sparse}ArrayCreate methods
        int length = node.getElements().size();
        float density = (float) (length - elision) / length;
        if ((density >= 0.25f && length < 0x10) || (density >= 0.75f && length < 0x1000)) {
            mv.loadExecutionContext();
            mv.anewarray(length, Types.Object);
            int nextIndex = 0;
            for (Expression element : node.getElements()) {
                if (element instanceof Elision) {
                // Elision
                } else {
                    mv.dup();
                    mv.iconst(nextIndex);
                    ValType elementType = element.accept(this, mv);
                    mv.toBoxed(elementType);
                    mv.astore(Types.Object);
                }
                nextIndex += 1;
            }
            if (elision == 0) {
                mv.invoke(Methods.ArrayObject_DenseArrayCreate);
            } else {
                mv.invoke(Methods.ArrayObject_SparseArrayCreate);
            }
        } else {
            // initialize with correct "length"
            ArrayCreate(length, mv);
            int nextIndex = 0;
            for (Expression element : node.getElements()) {
                if (element instanceof Elision) {
                // Elision
                } else {
                    mv.dup();
                    mv.iconst(nextIndex);
                    ArrayAccumulationElement(element, mv);
                }
                nextIndex += 1;
            }
            assert nextIndex == length;
        // Skip Put(array, "length", nextIndex, false), array is initialized with fixed length.
        }
    }
    return ValType.Object;
}
Also used : SpreadElementMethod(com.github.anba.es6draft.ast.synthetic.SpreadElementMethod) ValType(com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)

Aggregations

ValType (com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)21 Jump (com.github.anba.es6draft.compiler.assembler.Jump)4 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)3 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)2 Name (com.github.anba.es6draft.ast.scope.Name)2 SpreadElementMethod (com.github.anba.es6draft.ast.synthetic.SpreadElementMethod)2 MethodCode (com.github.anba.es6draft.compiler.assembler.Code.MethodCode)2 FieldName (com.github.anba.es6draft.compiler.assembler.FieldName)2 MethodTypeDescriptor (com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)2 com.github.anba.es6draft.ast (com.github.anba.es6draft.ast)1 Scope (com.github.anba.es6draft.ast.scope.Scope)1 TopLevelScope (com.github.anba.es6draft.ast.scope.TopLevelScope)1 WithScope (com.github.anba.es6draft.ast.scope.WithScope)1 ExpressionMethod (com.github.anba.es6draft.ast.synthetic.ExpressionMethod)1 EvaluateArrayComprehension (com.github.anba.es6draft.compiler.ArrayComprehensionGenerator.EvaluateArrayComprehension)1 OutlinedCall (com.github.anba.es6draft.compiler.CodeVisitor.OutlinedCall)1 PropertyEvaluation (com.github.anba.es6draft.compiler.PropertyGenerator.PropertyEvaluation)1 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)1 MutableValue (com.github.anba.es6draft.compiler.assembler.MutableValue)1 Type (com.github.anba.es6draft.compiler.assembler.Type)1