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;
}
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);
}
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;
}
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);
}
}
}
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;
}
Aggregations