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