/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.compiler; import com.github.anba.es6draft.ast.BindingIdentifier; import com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType; import com.github.anba.es6draft.compiler.assembler.MethodName; import com.github.anba.es6draft.compiler.assembler.Type; /** * Rename to VarBindingOp? */ abstract class IdReferenceOp { /** * <h1>8.3.1 ResolveBinding</h1> * <p> * Evaluates {@code node} and pushes the resolved reference object on the stack. * <p> * stack: [] -> [{@literal <reference>}] * * @param node * the reference node * @param mv * the code visitor * @return the reference value type */ abstract ValType resolveBinding(BindingIdentifier node, CodeVisitor mv); /** * <h1>6.2.3.2 PutValue (V, W)</h1> * <p> * Assigns a new value to the reference. * <p> * stack: [{@literal <reference>}, {@literal <value>}] -> [] * * @param node * the reference node * @param value * the top stack value type * @param mv * the code visitor */ abstract void putValue(BindingIdentifier node, ValType value, CodeVisitor mv); /** * Returns the {@code IdReferenceOp} implementation for the binding identifier. * * @param lhs * the binding identifier * @return the {@code IdReferenceOp} */ static IdReferenceOp of(BindingIdentifier ident) { return IdReferenceOp.LOOKUP; } private static final class Methods { // class: Reference static final MethodName Reference_putValue = MethodName.findVirtual(Types.Reference, "putValue", Type.methodType(Type.VOID_TYPE, Types.Object, Types.ExecutionContext)); } /** * 12.1.6 Runtime Semantics: Evaluation */ static final IdReferenceOp LOOKUP = new IdReferenceOp() { @Override ValType resolveBinding(BindingIdentifier node, CodeVisitor mv) { // stack: [] -> [ref] IdentifierResolution.resolve(node, mv); return ValType.Reference; } @Override void putValue(BindingIdentifier node, ValType value, CodeVisitor mv) { // stack: [ref, value] -> [] mv.toBoxed(value); mv.loadExecutionContext(); mv.lineInfo(node); mv.invoke(Methods.Reference_putValue); } }; }