use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionComponentEvaluation
* <p>
* ComprehensionFor : for ( ForBinding of AssignmentExpression )
*/
@Override
public Void visit(ComprehensionFor node, CodeVisitor mv) {
Jump lblTest = new Jump(), lblLoop = new Jump();
Variable<ScriptIterator<?>> iter = iterators.next();
/* steps 1-2 */
expressionBoxed(node.getExpression(), mv);
/* steps 3-4 */
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
mv.invoke(Methods.ScriptRuntime_iterate);
mv.store(iter);
/* step 5 (not applicable) */
/* step 6 */
mv.nonDestructiveGoTo(lblTest);
/* steps 6.d-e */
mv.mark(lblLoop);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_next);
/* steps 6.f-j */
BlockScope scope = node.getScope();
if (scope.isPresent()) {
mv.enterVariableScope();
Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> env = mv.newVariable("env", LexicalEnvironment.class).uncheckedCast();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
// stack: [nextValue] -> []
Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
mv.store(nextValue);
newDeclarativeEnvironment(scope, mv);
mv.store(env);
getEnvRec(env, envRec, mv);
for (Name name : BoundNames(node.getBinding())) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
}
BindingInitialization(codegen, envRec, node.getBinding(), nextValue, mv);
mv.load(env);
pushLexicalEnvironment(mv);
mv.exitVariableScope();
} else {
// stack: [nextValue] -> []
mv.pop();
}
/* step 6.k */
mv.enterScope(node);
new IterationGenerator<ComprehensionFor>(codegen) {
@Override
protected Completion iterationBody(ComprehensionFor node, Variable<ScriptIterator<?>> iterator, CodeVisitor mv) {
elements.next().accept(ComprehensionGenerator.this, mv);
return Completion.Normal;
}
@Override
protected MutableValue<Object> enterIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.enterIteration();
}
@Override
protected List<TempLabel> exitIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.exitIteration();
}
}.generate(node, iter, mv);
mv.exitScope();
/* steps 6.l-m */
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
/* steps 6.a-c */
mv.mark(lblTest);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_hasNext);
mv.ifne(lblLoop);
return null;
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord 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();
Variable<ArrayList<Callable>> classDecorators = null;
boolean hasClassDecorators = !def.getDecorators().isEmpty();
if (hasClassDecorators) {
classDecorators = newDecoratorVariable("classDecorators", mv);
evaluateDecorators(classDecorators, def.getDecorators(), mv);
}
mv.enterClassDefinition();
// step 1 (not applicable)
// steps 2-4
BlockScope scope = def.getScope();
assert (scope != null && scope.isPresent()) == (className != null);
Variable<DeclarativeEnvironmentRecord> classScopeEnvRec = null;
if (className != null) {
// stack: [] -> [classScope]
newDeclarativeEnvironment(scope, mv);
classScopeEnvRec = mv.newVariable("classScopeEnvRec", DeclarativeEnvironmentRecord.class);
getEnvRec(classScopeEnvRec, mv);
// stack: [classScope] -> [classScope]
Name innerName = scope.resolveName(className, false);
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.ScriptRuntime_getDefaultClassProto);
} else if (classHeritage instanceof NullLiteral) {
mv.loadExecutionContext();
mv.invoke(Methods.ScriptRuntime_getClassProto_Null);
} else {
expressionBoxed(classHeritage, mv);
mv.loadExecutionContext();
mv.lineInfo(def);
mv.invoke(Methods.ScriptRuntime_getClassProto);
}
// stack: [<constructorParent,proto>] -> [<constructorParent,proto>]
Variable<OrdinaryObject> proto = mv.newVariable("proto", OrdinaryObject.class);
mv.dup();
mv.aload(1, Types.ScriptObject);
mv.checkcast(Types.OrdinaryObject);
mv.store(proto);
// stack: [<constructorParent,proto>] -> [constructorParent, proto]
mv.aload(0, Types.ScriptObject);
mv.load(proto);
// steps 8-9
// stack: [constructorParent, proto] -> [constructorParent, proto, <rti>]
MethodDefinition constructor = ConstructorMethod(def);
assert constructor != null;
MethodName method = codegen.compile(def);
// 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.ScriptRuntime_EvaluateConstructorMethod);
// stack: [F] -> []
Variable<OrdinaryConstructorFunction> F = mv.newVariable("F", OrdinaryConstructorFunction.class);
mv.store(F);
Variable<ArrayList<Object>> methodDecorators = null;
boolean hasMethodDecorators = HasDecorators(def);
if (hasMethodDecorators) {
methodDecorators = newDecoratorVariable("methodDecorators", mv);
}
if (!constructor.getDecorators().isEmpty()) {
addDecoratorObject(methodDecorators, proto, mv);
evaluateDecorators(methodDecorators, constructor.getDecorators(), mv);
addDecoratorKey(methodDecorators, "constructor", mv);
}
// steps 19-21
ClassPropertyEvaluation(codegen, def.getProperties(), F, proto, methodDecorators, mv);
if (hasClassDecorators) {
mv.load(F);
mv.load(classDecorators);
mv.loadExecutionContext();
mv.lineInfo(def);
mv.invoke(Methods.ScriptRuntime_EvaluateClassDecorators);
}
if (hasMethodDecorators) {
mv.load(methodDecorators);
mv.loadExecutionContext();
mv.lineInfo(def);
mv.invoke(Methods.ScriptRuntime_EvaluateClassMethodDecorators);
}
// steps 22-23 (moved)
if (className != null) {
// stack: [] -> []
Name innerName = scope.resolveName(className, false);
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classScopeEnvRec, innerName);
op.initializeBinding(classScopeEnvRec, innerName, F, mv);
mv.exitScope();
popLexicalEnvironment(mv);
}
// stack: [] -> [F]
mv.load(F);
mv.exitVariableScope();
// step 24 (return F)
mv.exitClassDefinition();
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class EvalDeclarationInstantiationGenerator method declareBlockFunctions.
private <ENVREC extends EnvironmentRecord> void declareBlockFunctions(Script evalScript, HashSet<Name> declaredFunctionOrVarNames, Variable<ExecutionContext> context, Variable<LexicalEnvironment<ENVREC>> varEnv, Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> lexEnv, Variable<ENVREC> varEnvRec, Variable<Undefined> undef, InstructionVisitor mv) {
final boolean catchVar = codegen.isEnabled(CompatibilityOption.CatchVarStatement);
int idCounter = 0;
List<FunctionDeclaration> blockFunctions = evalScript.getScope().blockFunctions();
for (FunctionDeclaration f : blockFunctions) {
Name fn = f.getName();
Jump next = null;
if (isEnclosedByLexical(evalScript)) {
// Runtime check only necessary when enclosed by lexical declarations.
f.setLegacyBlockScopeId(++idCounter);
next = new Jump();
canDeclareVarBinding(varEnv, lexEnv, fn, catchVar, next, mv);
setLegacyBlockFunction(context, f, mv);
}
if (declaredFunctionOrVarNames.add(fn)) {
BindingOp<EnvironmentRecord> op = BindingOp.LOOKUP;
Jump varAlreadyDeclared = new Jump();
op.hasBinding(varEnvRec, fn, mv);
mv.ifne(varAlreadyDeclared);
{
op.createMutableBinding(varEnvRec, fn, true, mv);
op.initializeBinding(varEnvRec, fn, undef, mv);
}
mv.mark(varAlreadyDeclared);
}
if (next != null) {
mv.mark(next);
}
}
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class StatementGenerator method visit.
/**
* 14.1.20 Runtime Semantics: Evaluation
*/
@Override
public Completion visit(FunctionDeclaration node, CodeVisitor mv) {
/* B.3.3 Block-Level Function Declarations Web Legacy Compatibility Semantics */
if (node.isLegacyBlockScoped()) {
Name name = node.getIdentifier().getName();
TopLevelScope top = mv.getScope().getTop();
if (mv.isFunction()) {
assert top instanceof FunctionScope;
Name varName = ((FunctionScope) top).variableScope().resolveName(name, false);
assert varName != null && name != varName;
/* step 1.a.ii.3.1 */
Value<DeclarativeEnvironmentRecord> fenv = getVariableEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
/* steps 1.a.ii.3.5-6 */
BindingOp.of(fenv, varName).setMutableBinding(fenv, varName, asm -> {
Value<DeclarativeEnvironmentRecord> benv = getLexicalEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
BindingOp.of(benv, name).getBindingValue(benv, name, false, mv);
}, false, mv);
} else {
assert top instanceof ScriptScope;
Name varName = name;
int functionId = node.getLegacyBlockScopeId();
Jump isLegacyScoped = null;
if (functionId > 0) {
isLegacyScoped = new Jump();
mv.loadExecutionContext();
mv.iconst(functionId);
mv.invoke(Methods.ScriptRuntime_isLegacyBlockFunction);
mv.ifeq(isLegacyScoped);
}
// The variable environment record is either:
// 1. The global environment record for global (eval) scripts.
// 2. Or a (function) declarative environment record for eval in functions.
// 3. Or a script-context environment record for eval in JSR-223 scripting.
Value<EnvironmentRecord> genv = getVariableEnvironmentRecord(Types.EnvironmentRecord, mv);
BindingOp.of(genv, varName).setMutableBinding(genv, varName, asm -> {
Value<DeclarativeEnvironmentRecord> benv = getLexicalEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
BindingOp.of(benv, name).getBindingValue(benv, name, false, mv);
}, false, mv);
if (isLegacyScoped != null) {
mv.mark(isLegacyScoped);
}
}
}
/* step 1 */
return Completion.Empty;
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class ScriptRuntime method EvaluateFunctionExpression.
/**
* 14.1 Function Definitions
* <p>
* 14.1.21 Runtime Semantics: Evaluation
* <ul>
* <li>FunctionExpression : function ( FormalParameters ) { FunctionBody }
* <li>FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
* </ul>
*
* @param fd
* the function runtime info object
* @param cx
* the execution context
* @return the new function instance
*/
public static OrdinaryConstructorFunction EvaluateFunctionExpression(RuntimeInfo.Function fd, ExecutionContext cx) {
OrdinaryConstructorFunction closure;
if (!fd.is(RuntimeInfo.FunctionFlags.ScopedName)) {
/* step 1 (not applicable) */
/* step 2 */
LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
/* step 3 */
closure = ConstructorFunctionCreate(cx, FunctionKind.Normal, fd, scope);
/* step 4 */
MakeConstructor(cx, closure);
} else {
/* step 1 (not applicable) */
/* step 2 */
LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
/* step 3 */
LexicalEnvironment<DeclarativeEnvironmentRecord> funcEnv = newDeclarativeEnvironment(scope);
/* step 4 */
DeclarativeEnvironmentRecord envRec = funcEnv.getEnvRec();
/* step 5 */
String name = fd.functionName();
/* step 6 */
envRec.createImmutableBinding(name, false);
/* step 7 */
closure = ConstructorFunctionCreate(cx, FunctionKind.Normal, fd, funcEnv);
/* step 8 */
MakeConstructor(cx, closure);
/* step 9 */
SetFunctionName(closure, name);
/* step 10 */
envRec.initializeBinding(name, closure);
}
/* step 5/11 */
return closure;
}
Aggregations