use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class EvalDeclarationInstantiationGenerator method checkLexicalRedeclaration.
/**
* 18.2.1.2, steps 5.b-d
*/
private void checkLexicalRedeclaration(Script evalScript, Variable<ExecutionContext> context, Variable<? extends LexicalEnvironment<? extends EnvironmentRecord>> varEnv, Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> lexEnv, Set<Name> varNames, InstructionVisitor mv) {
Variable<LexicalEnvironment<EnvironmentRecord>> thisLex = mv.newVariable("thisLex", LexicalEnvironment.class).uncheckedCast();
Variable<EnvironmentRecord> thisEnvRec = mv.newVariable("thisEnvRec", EnvironmentRecord.class).uncheckedCast();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class).uncheckedCast();
Set<Name> varForOfNames = evalScript.getScope().varForOfDeclaredNames();
final boolean catchVar = codegen.isEnabled(CompatibilityOption.CatchVarStatement);
final boolean hasWith = codegen.isEnabled(Parser.Option.EnclosedByWithStatement);
Jump loopTest = new Jump(), loop = new Jump(), objectEnv = new Jump();
mv.load(lexEnv);
if (hasLexicalEnvironment(evalScript)) {
// Don't need to check own lexical environment.
mv.invoke(Methods.LexicalEnvironment_getOuter);
}
mv.store(thisLex);
mv.nonDestructiveGoTo(loopTest);
{
mv.mark(loop);
getEnvironmentRecord(thisLex, thisEnvRec, mv);
if (hasWith) {
mv.load(thisEnvRec);
mv.instanceOf(Types.ObjectEnvironmentRecord);
mv.ifne(objectEnv);
}
mv.load(thisEnvRec);
mv.checkcast(Types.DeclarativeEnvironmentRecord);
mv.store(envRec);
for (Name name : varNames) {
mv.load(context);
mv.load(envRec);
mv.aconst(name.getIdentifier());
mv.iconst(catchVar && !varForOfNames.contains(name));
mv.invoke(Methods.ScriptRuntime_canDeclareVarOrThrow);
}
if (hasWith) {
mv.mark(objectEnv);
}
mv.load(thisLex);
mv.invoke(Methods.LexicalEnvironment_getOuter);
mv.store(thisLex);
}
mv.mark(loopTest);
mv.load(thisLex);
mv.load(varEnv);
mv.ifacmpne(loop);
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class BlockDeclarationInstantiationGenerator method generate.
private void generate(List<Declaration> declarations, Variable<ExecutionContext> cx, Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> env, InstructionVisitor mv) {
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
Variable<FunctionObject> fo = null;
getEnvironmentRecord(env, envRec, mv);
/* steps 1-2 */
for (Declaration d : declarations) {
if (!(d instanceof HoistableDeclaration)) {
for (Name dn : BoundNames(d)) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, dn);
if (IsConstantDeclaration(d)) {
op.createImmutableBinding(envRec, dn, true, mv);
} else {
op.createMutableBinding(envRec, dn, false, mv);
}
}
} else {
Name fn = BoundName((HoistableDeclaration) d);
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, fn);
op.createMutableBinding(envRec, fn, false, mv);
InstantiateFunctionObject(cx, env, d, mv);
if (fo == null) {
fo = mv.newVariable("fo", FunctionObject.class);
}
mv.store(fo);
op.initializeBinding(envRec, fn, fo, mv);
}
}
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionEvaluation
*/
@Override
public Void visit(LegacyComprehension node, CodeVisitor mv) {
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);
newDeclarativeEnvironment(scope, mv);
mv.store(env);
getEnvRec(env, envRec, mv);
for (Name name : LexicallyDeclaredNames(node.getScope())) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
InitializeBoundNameWithUndefined(envRec, name, mv);
}
mv.load(env);
pushLexicalEnvironment(mv);
mv.exitVariableScope();
}
mv.enterScope(node);
visit((Comprehension) node, mv);
mv.exitScope();
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
return null;
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class ExpressionGenerator method visit.
/**
* Extension: 'let' expression
*/
@Override
public ValType visit(LetExpression node, CodeVisitor mv) {
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);
newDeclarativeEnvironment(scope, mv);
mv.store(env);
getEnvRec(env, envRec, mv);
for (LexicalBinding lexical : node.getBindings()) {
Binding binding = lexical.getBinding();
Expression initializer = lexical.getInitializer();
for (Name name : BoundNames(binding)) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
}
if (initializer == null) {
// LexicalBinding : BindingIdentifier
assert binding instanceof BindingIdentifier;
Name name = ((BindingIdentifier) binding).getName();
/* steps 1-2 */
// stack: [] -> []
InitializeBoundNameWithUndefined(envRec, name, mv);
} else if (binding instanceof BindingIdentifier) {
// LexicalBinding : BindingIdentifier Initializer
Name name = ((BindingIdentifier) binding).getName();
/* steps 1-7 */
InitializeBoundNameWithInitializer(codegen, envRec, name, initializer, mv);
} else {
// LexicalBinding : BindingPattern Initializer
assert binding instanceof BindingPattern;
/* steps 1-3 */
expressionBoxed(initializer, mv);
/* steps 4-5 */
BindingInitializationGenerator.BindingInitialization(codegen, envRec, (BindingPattern) binding, mv);
}
}
mv.load(env);
pushLexicalEnvironment(mv);
mv.exitVariableScope();
}
mv.enterScope(node);
ValType type = node.getExpression().accept(this, mv);
mv.exitScope();
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
return type;
}
use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.
the class DeclarationBindingInstantiation method EvalDeclarationInstantiation.
/**
* 18.2.1.2 Runtime Semantics: EvalDeclarationInstantiation (body, varEnv, lexEnv, strict)
*
* @param cx
* the execution context
* @param evalScript
* the global script to instantiate
* @param varEnv
* the variable environment
* @param lexEnv
* the lexical environment
*/
public static void EvalDeclarationInstantiation(ExecutionContext cx, Script evalScript, LexicalEnvironment<?> varEnv, LexicalEnvironment<DeclarativeEnvironmentRecord> lexEnv) {
boolean strict = evalScript.isStrict();
boolean nonStrictGlobal = !strict && evalScript.isGlobalCode() && !evalScript.isScripting();
/* step 1 */
Set<Name> varNames = VarDeclaredNames(evalScript);
/* step 2 */
List<StatementListItem> varDeclarations = VarScopedDeclarations(evalScript);
/* step 3 (not applicable) */
/* step 4 */
EnvironmentRecord varEnvRec = varEnv.getEnvRec();
assert !nonStrictGlobal || varEnvRec instanceof GlobalEnvironmentRecord : String.format("Unexpected environment record type: %s", varEnvRec);
/* step 5 */
if (!strict) {
if (nonStrictGlobal) {
/* step 5.a */
GlobalEnvironmentRecord gEnvRec = (GlobalEnvironmentRecord) varEnvRec;
for (Name name : varNames) {
ScriptRuntime.canDeclareVarScopedOrThrow(cx, gEnvRec, name.getIdentifier());
}
}
/* steps 5.b-d */
if (!evalScript.isScripting() && !varNames.isEmpty() && isEnclosedByLexicalOrHasVarForOf(evalScript)) {
checkLexicalRedeclaration(cx, varEnv, lexEnv, varNames);
}
}
/* steps 6-8 (not applicable) */
/* step 9 */
LinkedHashSet<Name> declaredNames = new LinkedHashSet<>();
/* step 10 */
for (StatementListItem d : varDeclarations) {
assert d instanceof VariableStatement;
for (Name vn : BoundNames((VariableStatement) d)) {
if (nonStrictGlobal) {
GlobalEnvironmentRecord gEnvRec = (GlobalEnvironmentRecord) varEnvRec;
ScriptRuntime.canDeclareGlobalVarOrThrow(cx, gEnvRec, vn.getIdentifier());
}
declaredNames.add(vn);
}
}
/* steps 12-13 */
assert LexicallyScopedDeclarations(evalScript).isEmpty();
/* step 15 */
for (Name vn : declaredNames) {
if (nonStrictGlobal) {
GlobalEnvironmentRecord gEnvRec = (GlobalEnvironmentRecord) varEnvRec;
gEnvRec.createGlobalVarBinding(vn.getIdentifier(), true);
} else {
boolean bindingExists = varEnvRec.hasBinding(vn.getIdentifier());
if (!bindingExists) {
varEnvRec.createMutableBinding(vn.getIdentifier(), true);
varEnvRec.initializeBinding(vn.getIdentifier(), UNDEFINED);
}
}
}
/* step 16 (return) */
}
Aggregations