use of com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction in project es6draft by anba.
the class CodeGenerator method compile.
MethodName compile(MethodDefinitionsMethod node, boolean hasDecorators, CodeVisitor mv) {
if (!isCompiled(node)) {
MethodCode method = newMethod(node);
MethodDefinitionsCodeVisitor body = new MethodDefinitionsCodeVisitor(node, method, mv);
body.lineInfo(node);
body.begin();
Variable<OrdinaryConstructorFunction> function = body.getFunctionParameter();
Variable<OrdinaryObject> proto = body.getPrototypeParameter();
Variable<ArrayList<Object>> decorators = hasDecorators ? body.getDecoratorsParameter() : null;
ClassPropertyEvaluation(this, node.getProperties(), function, proto, decorators, body);
body._return();
body.end();
}
return methodDesc(node);
}
use of com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction in project es6draft by anba.
the class ClassOperations method EvaluateConstructorMethod.
/**
* 14.3 Method Definitions, 14.5 Class Definitions
* <p>
* 14.3.8 Runtime Semantics: DefineMethod<br>
* 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
*
* @param constructorParent
* the constructor prototype
* @param proto
* the class prototype
* @param fd
* the function runtime info object
* @param isDerived
* {@code true} if evaluating the constructor of a derived class
* @param cx
* the execution context
* @return the new function instance
*/
public static OrdinaryConstructorFunction EvaluateConstructorMethod(ScriptObject constructorParent, OrdinaryObject proto, RuntimeInfo.Function fd, boolean isDerived, ExecutionContext cx) {
// ClassDefinitionEvaluation - steps 12-14 (call DefineMethod)
LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
ConstructorKind constructorKind = isDerived ? ConstructorKind.Derived : ConstructorKind.Base;
OrdinaryConstructorFunction constructor = ConstructorFunctionCreate(cx, FunctionKind.ClassConstructor, constructorKind, fd, scope, constructorParent);
MakeMethod(constructor, proto);
// ClassDefinitionEvaluation - step 15 (not applicable, cf. ConstructorFunctionCreate)
// ClassDefinitionEvaluation - step 16
MakeConstructor(constructor, false, proto);
// ClassDefinitionEvaluation - step 17
MakeClassConstructor(constructor);
// ClassDefinitionEvaluation - step 18
proto.defineOwnProperty(cx, "constructor", new PropertyDescriptor(constructor, true, false, true));
return constructor;
}
use of com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction in project es6draft by anba.
the class FunctionOperations method InstantiateFunctionObject.
/**
* 14.1 Function Definitions
* <p>
* 14.1.20 Runtime Semantics: InstantiateFunctionObject
*
* @param scope
* the current lexical scope
* @param cx
* the execution context
* @param fd
* the function runtime info object
* @return the new function instance
*/
public static OrdinaryConstructorFunction InstantiateFunctionObject(LexicalEnvironment<?> scope, ExecutionContext cx, RuntimeInfo.Function fd) {
/* step 1 (not applicable) */
/* step 2 */
String name = fd.functionName();
/* step 3 */
OrdinaryConstructorFunction f = ConstructorFunctionCreate(cx, FunctionKind.Normal, fd, scope);
/* step 4 */
MakeConstructor(cx, f);
/* step 4 */
SetFunctionName(f, name);
/* step 6 */
return f;
}
use of com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction in project es6draft by anba.
the class FunctionConstructor method CreateDynamicFunction.
/**
* 19.2.1.1.1 RuntimeSemantics: CreateDynamicFunction(constructor, newTarget, kind, args)
*
* @param cx
* the execution context
* @param kind
* the function kind
* @param compiledFunction
* the compiled function
* @param proto
* the function prototype
* @return the new function object
*/
public static FunctionObject CreateDynamicFunction(ExecutionContext cx, SourceKind kind, CompiledFunction compiledFunction, ScriptObject proto) {
RuntimeInfo.Function function = compiledFunction.getFunction();
/* step 18 */
boolean strict = function.isStrict();
/* step 30 */
ObjectAllocator<? extends FunctionObject> allocator;
switch(kind) {
case AsyncFunction:
allocator = OrdinaryAsyncFunction::new;
break;
case AsyncGenerator:
allocator = OrdinaryAsyncGenerator::new;
break;
case Function:
if (function.is(RuntimeInfo.FunctionFlags.Legacy)) {
assert !strict;
allocator = LegacyConstructorFunction::new;
} else {
allocator = OrdinaryConstructorFunction::new;
}
break;
case Generator:
allocator = OrdinaryGenerator::new;
break;
default:
throw new AssertionError();
}
FunctionObject f = FunctionAllocate(cx, allocator, proto, strict, FunctionKind.Normal);
/* steps 31-32 */
LexicalEnvironment<GlobalEnvironmentRecord> scope = f.getRealm().getGlobalEnv();
/* step 33 */
FunctionInitialize(f, FunctionKind.Normal, function, scope, compiledFunction);
/* steps 34-36 */
switch(kind) {
case AsyncFunction:
/* step 36 */
break;
case AsyncGenerator:
{
OrdinaryObject prototype = ObjectCreate(cx, Intrinsics.AsyncGeneratorPrototype);
f.infallibleDefineOwnProperty("prototype", new Property(prototype, true, false, false));
break;
}
case Function:
/* step 35 */
if (f instanceof LegacyConstructorFunction) {
MakeConstructor(cx, (LegacyConstructorFunction) f);
} else {
MakeConstructor(cx, (OrdinaryConstructorFunction) f);
}
break;
case Generator:
{
/* step 34 */
OrdinaryObject prototype = ObjectCreate(cx, Intrinsics.GeneratorPrototype);
f.infallibleDefineOwnProperty("prototype", new Property(prototype, true, false, false));
break;
}
default:
throw new AssertionError();
}
/* step 37 */
SetFunctionName(f, "anonymous");
/* step 38 */
return f;
}
use of com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction in project es6draft by anba.
the class DefaultCodeGenerator method ClassDefinitionEvaluation.
/**
* 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
*
* @param def
* the class definition node
* @param className
* the class name or {@code null} if not present
* @param mv
* the code visitor
*/
protected final void ClassDefinitionEvaluation(ClassDefinition def, Name className, CodeVisitor mv) {
mv.enterVariableScope();
List<Expression> classDecoratorsList = def.getDecorators();
Variable<Callable[]> classDecorators = null;
if (!classDecoratorsList.isEmpty()) {
classDecorators = mv.newVariable("classDecorators", Callable[].class);
mv.anewarray(classDecoratorsList.size(), Types.Callable);
mv.store(classDecorators);
int index = 0;
for (Expression decorator : classDecoratorsList) {
mv.astore(classDecorators, index++, __ -> {
expressionBoxed(decorator, mv);
CheckCallable(decorator, mv);
});
}
}
mv.enterClassDefinition();
// step 1 (not applicable)
// steps 2-4
BlockScope scope = def.getScope();
Variable<DeclarativeEnvironmentRecord> classScopeEnvRec = null;
if (scope != null) {
assert scope.isPresent() == (className != null);
if (scope.isPresent()) {
// stack: [] -> [classScope]
newDeclarativeEnvironment(scope, mv);
classScopeEnvRec = mv.newVariable("classScopeEnvRec", DeclarativeEnvironmentRecord.class);
getEnvRec(classScopeEnvRec, mv);
if (className != null) {
// stack: [classScope] -> [classScope]
Name innerName = scope.resolveName(className);
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classScopeEnvRec, innerName);
op.createImmutableBinding(classScopeEnvRec, innerName, true, mv);
}
// stack: [classScope] -> []
pushLexicalEnvironment(mv);
}
mv.enterScope(def);
}
// steps 5-7
// stack: [] -> [<constructorParent,proto>]
Expression classHeritage = def.getHeritage();
if (classHeritage == null) {
mv.loadExecutionContext();
mv.invoke(Methods.ClassOperations_getDefaultClassProto);
} else if (classHeritage instanceof NullLiteral) {
mv.loadExecutionContext();
mv.invoke(Methods.ClassOperations_getClassProto_Null);
} else {
expressionBoxed(classHeritage, mv);
mv.loadExecutionContext();
mv.lineInfo(def);
mv.invoke(Methods.ClassOperations_getClassProto);
}
// stack: [<protoParent,constructorParent>] -> [<protoParent,constructorParent>]
Variable<OrdinaryObject> proto = mv.newVariable("proto", OrdinaryObject.class);
mv.dup();
mv.aload(0, Types.ScriptObject);
mv.loadExecutionContext();
mv.invoke(Methods.ClassOperations_createProto);
mv.store(proto);
// stack: [<protoParent,constructorParent>] -> [constructorParent, proto]
mv.aload(1, Types.ScriptObject);
mv.load(proto);
// Push the private-name environment to ensure private names are accessible in the constructor.
BlockScope bodyScope = def.getBodyScope();
if (bodyScope != null) {
List<Name> privateBoundNames = PrivateBoundNames(def);
assert bodyScope.isPresent() == !privateBoundNames.isEmpty();
if (bodyScope.isPresent()) {
// stack: [] -> [classPrivateEnv]
newDeclarativeEnvironment(bodyScope, mv);
Variable<DeclarativeEnvironmentRecord> classPrivateEnvRec = mv.newVariable("classPrivateEnvRec", DeclarativeEnvironmentRecord.class);
getEnvRec(classPrivateEnvRec, mv);
HashSet<Name> declaredPrivateNames = new HashSet<>();
for (Name name : privateBoundNames) {
// FIXME: spec bug - missing check for already declared private names for getter/setter pairs
if (declaredPrivateNames.add(name)) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classPrivateEnvRec, name);
op.createImmutableBinding(classPrivateEnvRec, name, true, mv);
}
}
// stack: [classPrivateEnv] -> []
pushLexicalEnvironment(mv);
}
mv.enterScope(bodyScope);
}
// steps 8-9
// stack: [constructorParent, proto] -> [constructorParent, proto, <rti>]
MethodName method = mv.compile(def, codegen::classDefinition);
// Runtime Semantics: Evaluation -> MethodDefinition
mv.invoke(method);
// step 10 (not applicable)
// steps 11-18
// stack: [constructorParent, proto, <rti>] -> [F]
mv.iconst(classHeritage != null);
mv.loadExecutionContext();
mv.lineInfo(def);
mv.invoke(Methods.ClassOperations_EvaluateConstructorMethod);
// stack: [F] -> []
Variable<OrdinaryConstructorFunction> F = mv.newVariable("F", OrdinaryConstructorFunction.class);
mv.store(F);
// steps 19-21
ClassPropertyGenerator.Result result = ClassPropertyEvaluation(codegen, def, F, proto, mv);
Variable<Object[]> methodDecorators = result.methodDecorators;
if (!classDecoratorsList.isEmpty()) {
int index = 0;
for (Expression decorator : classDecoratorsList) {
mv.aload(classDecorators, index++, Types.Callable);
invokeDynamicCall(mv, decorator, mv.executionContext(), mv.undefinedValue(), F);
mv.pop();
}
}
if (methodDecorators != null) {
LabelledHashKey hashKey = new LabelledHashKey(def, "decorators");
MethodName decoratorsMethod = mv.compile(hashKey, () -> classMethodDecorators(def, mv));
// 0 = hint for stacktraces to omit this frame
mv.lineInfo(0);
mv.invoke(decoratorsMethod, mv.executionContext(), F, proto, methodDecorators);
}
if (scope != null) {
// steps 22-23 (moved)
if (className != null) {
// stack: [] -> []
Name innerName = scope.resolveName(className);
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classScopeEnvRec, innerName);
op.initializeBinding(classScopeEnvRec, innerName, F, mv);
}
}
if (result.instanceClassField != null || result.instanceClassMethods != null) {
MethodName initializer = compileClassFieldInitializer(def, MethodDefinition.MethodAllocation.Prototype, mv);
// stack: [] -> [F]
mv.load(F);
// stack: [F] -> [F, initializer]
mv.load(proto);
mv.invoke(initializer);
if (result.instanceClassField != null) {
mv.load(result.instanceClassField);
} else {
mv.anull();
}
if (result.instanceClassMethods != null) {
mv.load(result.instanceClassMethods);
} else {
mv.anull();
}
mv.loadExecutionContext();
mv.invoke(Methods.ClassOperations_CreateClassFieldInitializer);
// stack: [F, initializer] -> []
mv.invoke(Methods.ClassOperations_setInstanceFieldsInitializer);
}
// Class fields: Call InitializeStaticFields.
if (result.staticClassField != null) {
MethodName initializer = compileClassFieldInitializer(def, MethodDefinition.MethodAllocation.Class, mv);
// stack: [] -> [staticInitializer]
mv.load(F);
mv.invoke(initializer);
mv.load(result.staticClassField);
mv.loadExecutionContext();
mv.invoke(Methods.ClassOperations_CreateStaticClassFieldInitializer);
// stack: [staticInitializer] -> []
invokeDynamicCall(mv, def, mv.executionContext(), F);
mv.pop(ValType.Any);
}
if (bodyScope != null) {
mv.exitScope();
if (bodyScope.isPresent()) {
popLexicalEnvironment(mv);
}
}
if (scope != null) {
mv.exitScope();
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
}
// stack: [] -> [F]
mv.load(F);
mv.exitVariableScope();
// step 24 (return F)
mv.exitClassDefinition();
}
Aggregations