Search in sources :

Example 6 with PrivateName

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

the class ClassPropertyGenerator method visit.

@Override
public Void visit(MethodDefinition node, CodeVisitor mv) {
    // Synthetic methods are handled elsewhere.
    if (node.isSynthetic()) {
        return null;
    }
    if (node.isClassConstructor() || node.isCallConstructor()) {
        if (!node.getDecorators().isEmpty()) {
            assert node.isClassConstructor() : "call constructors cannot have decorators";
            // Evaluate constructor decorators in source order.
            for (Expression decorator : node.getDecorators()) {
                decorators.store(__ -> {
                    expressionBoxed(decorator, mv);
                    CheckCallable(decorator, mv);
                }, mv);
            }
            decorators.store(mv.vconst("constructor"), mv);
        }
        return null;
    }
    MethodName method = mv.compile(node, codegen::methodDefinition);
    ClassElementName classElementName = node.getClassElementName();
    boolean isPrivateName = classElementName instanceof PrivateNameProperty;
    assert !isPrivateName || node.getDecorators().isEmpty();
    for (Expression decorator : node.getDecorators()) {
        decorators.store(__ -> {
            expressionBoxed(decorator, mv);
            CheckCallable(decorator, mv);
        }, mv);
    }
    mv.load(node.isStatic() ? constructor : prototype);
    if (!isPrivateName) {
        // stack: [<object>] -> [<object>, propertyName, <object>, propertyName]
        String propName = PropName(classElementName.toPropertyName());
        if (propName == null) {
            assert node.getPropertyName() instanceof ComputedPropertyName;
            node.getPropertyName().accept(this, mv);
            if (!node.getDecorators().isEmpty()) {
                mv.dup();
                mv.store(decorators.element(Object.class, mv));
            }
        } else {
            if (!node.getDecorators().isEmpty()) {
                decorators.store(mv.vconst(propName), mv);
            }
            mv.aconst(propName);
        }
        mv.dup2();
    } else {
        mv.enterVariableScope();
        Variable<PrivateName> privateName = mv.newVariable("privateName", PrivateName.class);
        // stack: [<object>] -> [<object>]
        InitializeOrGetPrivateName((PrivateNameProperty) classElementName, isPrivateNameInitialized(node), privateName, mv);
        // stack: [<object>] -> [<object>, privateName]
        mv.load(privateName);
        if (node.isStatic()) {
            // stack: [<object>, privateName] -> [<object>, privateName, <object>, privateName]
            mv.dup2();
        } else {
            // stack: [<object>, privateName] -> [privateName, <object>, privateName]
            mv.dupX1();
        }
        mv.exitVariableScope();
    }
    mv.invoke(method);
    mv.loadExecutionContext();
    mv.lineInfo(node);
    // stack: [..., <object>, propertyName, rti, cx] -> [..., method]
    switch(node.getType()) {
        case AsyncFunction:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinitionAsync);
            break;
        case AsyncGenerator:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinitionAsyncGenerator);
            break;
        case Function:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinition);
            break;
        case Generator:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinitionGenerator);
            break;
        case Getter:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinitionGetter);
            break;
        case Setter:
            mv.invoke(Methods.FunctionOperations_EvaluatePropertyDefinitionSetter);
            break;
        case CallConstructor:
        case ClassConstructor:
        default:
            throw new AssertionError("invalid method type");
    }
    if (!isPrivateName) {
        // stack: [<object>, propertyName, method] -> []
        mv.loadExecutionContext();
        switch(node.getType()) {
            case AsyncFunction:
            case AsyncGenerator:
            case Function:
            case Generator:
                mv.invoke(Methods.ClassOperations_defineMethod);
                break;
            case Getter:
                mv.invoke(Methods.ClassOperations_defineGetter);
                break;
            case Setter:
                mv.invoke(Methods.ClassOperations_defineSetter);
                break;
            case CallConstructor:
            case ClassConstructor:
            default:
                throw new AssertionError("invalid method type");
        }
    } else {
        if (node.isStatic()) {
            // Static class methods can be defined directly.
            // stack: [<object>, privateName, method] -> []
            mv.loadExecutionContext();
            switch(node.getType()) {
                case AsyncFunction:
                case AsyncGenerator:
                case Function:
                case Generator:
                    mv.invoke(Methods.ClassOperations_definePrivateMethod);
                    break;
                case Getter:
                    mv.invoke(Methods.ClassOperations_definePrivateGetter);
                    break;
                case Setter:
                    mv.invoke(Methods.ClassOperations_definePrivateSetter);
                    break;
                case CallConstructor:
                case ClassConstructor:
                default:
                    throw new AssertionError("invalid method type");
            }
        } else {
            // stack: [privateName, method] -> []
            switch(node.getType()) {
                case AsyncFunction:
                case AsyncGenerator:
                case Function:
                case Generator:
                    mv.get(Fields.InstanceMethodKind_Method);
                    break;
                case Getter:
                    mv.get(Fields.InstanceMethodKind_Getter);
                    break;
                case Setter:
                    mv.get(Fields.InstanceMethodKind_Setter);
                    break;
                case CallConstructor:
                case ClassConstructor:
                default:
                    throw new AssertionError("invalid method type");
            }
            mv.invoke(Methods.ClassOperations_newInstanceMethod);
            instanceMethods.element(InstanceMethod.class, mv).store(mv);
        }
    }
    return null;
}
Also used : PrivateName(com.github.anba.es6draft.runtime.types.PrivateName) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) InstanceMethod(com.github.anba.es6draft.runtime.language.ClassOperations.InstanceMethod)

Example 7 with PrivateName

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

the class ClassPropertyGenerator method InitializeOrGetPrivateName.

private void InitializeOrGetPrivateName(PrivateNameProperty privateName, boolean isAlreadyDefined, MutableValue<PrivateName> privateNameVar, CodeVisitor mv) {
    // TODO: The spec uses a separate lexical environment for private names.
    Name name = privateName.getName();
    Value<DeclarativeEnvironmentRecord> scopeEnvRec = getLexicalEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
    BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(scopeEnvRec, name);
    if (isAlreadyDefined) {
        op.getBindingValue(scopeEnvRec, name, true, mv);
        mv.checkcast(Types.PrivateName);
        mv.store(privateNameVar);
    } else {
        mv.anew(Methods.PrivateName_new, mv.vconst(name.getIdentifier()));
        mv.store(privateNameVar);
        op.initializeBinding(scopeEnvRec, name, privateNameVar, mv);
    }
}
Also used : DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) PropName(com.github.anba.es6draft.semantics.StaticSemantics.PropName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) FieldName(com.github.anba.es6draft.compiler.assembler.FieldName) PrivateName(com.github.anba.es6draft.runtime.types.PrivateName)

Example 8 with PrivateName

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

the class ClassOperations method DefineField.

public static void DefineField(Object fieldName, Object initValue, ExecutionContext cx) {
    EnvironmentRecord envRec = cx.getThisEnvironment();
    assert envRec instanceof FunctionEnvironmentRecord;
    FunctionEnvironmentRecord fEnvRec = (FunctionEnvironmentRecord) envRec;
    assert fEnvRec.getThisBindingStatus() == FunctionEnvironmentRecord.ThisBindingStatus.Initialized;
    assert fEnvRec.getThisValue() instanceof ScriptObject;
    ScriptObject receiver = (ScriptObject) fEnvRec.getThisValue();
    if (fieldName instanceof PrivateName) {
        PrivateName name = (PrivateName) fieldName;
        Property desc = new Property(initValue, true, false, false);
        privateFieldDefine(cx, receiver, name, desc);
    } else {
        assert IsPropertyKey(fieldName);
        CreateDataPropertyOrThrow(cx, receiver, fieldName, initValue);
    }
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) PrivateName(com.github.anba.es6draft.runtime.types.PrivateName) FunctionEnvironmentRecord(com.github.anba.es6draft.runtime.FunctionEnvironmentRecord) FunctionEnvironmentRecord(com.github.anba.es6draft.runtime.FunctionEnvironmentRecord) EnvironmentRecord(com.github.anba.es6draft.runtime.EnvironmentRecord) Property(com.github.anba.es6draft.runtime.types.Property)

Aggregations

PrivateName (com.github.anba.es6draft.runtime.types.PrivateName)8 Property (com.github.anba.es6draft.runtime.types.Property)4 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)4 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)3 DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)3 Name (com.github.anba.es6draft.ast.scope.Name)2 FieldName (com.github.anba.es6draft.compiler.assembler.FieldName)2 EnvironmentRecord (com.github.anba.es6draft.runtime.EnvironmentRecord)2 FunctionEnvironmentRecord (com.github.anba.es6draft.runtime.FunctionEnvironmentRecord)2 Callable (com.github.anba.es6draft.runtime.types.Callable)2 OrdinaryObject (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject)2 PropName (com.github.anba.es6draft.semantics.StaticSemantics.PropName)2 InstanceMethod (com.github.anba.es6draft.runtime.language.ClassOperations.InstanceMethod)1 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)1 HashSet (java.util.HashSet)1