use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.
the class DefaultCodeGenerator method SetFunctionName.
/**
* stack: [function] {@literal ->} [function]
*
* @param node
* the function or class node
* @param name
* the new function name
* @param mv
* the code visitor
*/
protected static void SetFunctionName(Node node, String name, CodeVisitor mv) {
Jump hasOwnName = null;
switch(hasOwnNameProperty(node)) {
case HasOwn:
return;
case HasComputed:
emitHasOwnNameProperty(mv);
hasOwnName = new Jump();
mv.ifne(hasOwnName);
default:
}
// stack: [function] -> [function, function, name]
mv.dup();
mv.aconst(name);
// stack: [function, function, name] -> [function]
mv.invoke(Methods.OrdinaryFunction_SetFunctionName_String);
if (hasOwnName != null) {
mv.mark(hasOwnName);
}
}
use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.
the class DefaultCodeGenerator method delegatedYield.
/**
* 14.4 Generator Function Definitions
* <p>
* 14.4.14 Runtime Semantics: Evaluation
* <ul>
* <li>YieldExpression : yield * AssignmentExpression
* </ul>
* <p>
* stack: [value] {@literal ->} [value']
*
* @param node
* the expression node
* @param mv
* the code visitor
*/
protected final void delegatedYield(Expression node, CodeVisitor mv) {
if (!mv.isAsync()) {
delegatedYield(node, (iterator, received) -> {
IteratorNext(node, iterator, received, mv);
}, (iterator, received) -> {
mv.loadExecutionContext();
mv.load(iterator);
mv.load(received);
mv.checkcast(Types.ScriptException);
mv.invoke(Methods.ScriptRuntime_yieldThrowCompletion);
}, (iterator, received) -> {
mv.loadExecutionContext();
mv.load(iterator);
mv.load(received);
mv.checkcast(Types.ReturnValue);
mv.invoke(Methods.ScriptRuntime_yieldReturnCompletion);
}, mv);
} else {
delegatedYield(node, (iterator, received) -> {
IteratorNext(node, iterator, received, mv);
await(node, mv);
// FIXME: spec bug - missing type check
requireObjectResult(node, "next", mv);
}, (iterator, received) -> {
mv.enterVariableScope();
Variable<Callable> throwMethod = mv.newVariable("throwMethod", Callable.class);
GetMethod(node, iterator, "throw", mv);
mv.store(throwMethod);
Jump noThrow = new Jump(), nextYield = new Jump();
mv.load(throwMethod);
mv.ifnull(noThrow);
{
InvokeMethod(node, mv, throwMethod, iterator, __ -> {
mv.load(received);
mv.checkcast(Types.ScriptException);
mv.invoke(Methods.ScriptException_getValue);
});
await(node, mv);
requireObjectResult(node, "throw", mv);
mv.goTo(nextYield);
}
mv.mark(noThrow);
{
asyncIteratorClose(node, iterator, mv);
reportPropertyNotCallable(node, "throw", mv);
mv.athrow();
}
mv.mark(nextYield);
mv.exitVariableScope();
}, (iterator, received) -> {
mv.enterVariableScope();
Variable<Callable> returnMethod = mv.newVariable("returnMethod", Callable.class);
GetMethod(node, iterator, "return", mv);
mv.store(returnMethod);
Jump noReturn = new Jump(), nextYield = new Jump();
mv.load(returnMethod);
mv.ifnull(noReturn);
{
InvokeMethod(node, mv, returnMethod, iterator, __ -> {
mv.load(received);
mv.checkcast(Types.ReturnValue);
mv.invoke(Methods.ReturnValue_getValue);
});
await(node, mv);
requireObjectResult(node, "return", mv);
mv.goTo(nextYield);
}
mv.mark(noReturn);
{
mv.anull();
}
mv.mark(nextYield);
mv.exitVariableScope();
}, mv);
}
}
use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.
the class DefaultCodeGenerator method ToBoolean.
/**
* stack: [Object] {@literal ->} [boolean]
*
* @param from
* the input value type
* @param mv
* the code visitor
*/
protected static final void ToBoolean(ValType from, CodeVisitor mv) {
switch(from) {
case Number:
mv.invoke(Methods.AbstractOperations_ToBoolean_double);
return;
case Number_int:
mv.i2d();
mv.invoke(Methods.AbstractOperations_ToBoolean_double);
return;
case Number_uint:
mv.l2d();
mv.invoke(Methods.AbstractOperations_ToBoolean_double);
return;
case Undefined:
case Null:
mv.pop();
mv.iconst(false);
return;
case Boolean:
return;
case String:
{
Jump l0 = new Jump(), l1 = new Jump();
mv.invoke(Methods.CharSequence_length);
mv.ifeq(l0);
mv.iconst(true);
mv.goTo(l1);
mv.mark(l0);
mv.iconst(false);
mv.mark(l1);
return;
}
case Object:
mv.pop();
mv.iconst(true);
return;
case Any:
mv.invoke(Methods.AbstractOperations_ToBoolean);
return;
case Empty:
case Reference:
default:
throw new AssertionError();
}
}
use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.
the class DefaultCodeGenerator method SetFunctionName.
/**
* stack: [propertyKey, function] {@literal ->} [propertyKey, function]
*
* @param node
* the function or class node
* @param propertyKeyType
* the property key value type
* @param mv
* the code visitor
*/
protected static void SetFunctionName(Node node, ValType propertyKeyType, CodeVisitor mv) {
Jump hasOwnName = null;
switch(hasOwnNameProperty(node)) {
case HasOwn:
return;
case HasComputed:
emitHasOwnNameProperty(mv);
hasOwnName = new Jump();
mv.ifne(hasOwnName);
default:
}
// stack: [propertyKey, function] -> [propertyKey, function, function, propertyKey]
mv.dup2();
mv.swap();
if (propertyKeyType == ValType.String) {
mv.invoke(Methods.OrdinaryFunction_SetFunctionName_String);
} else {
assert propertyKeyType == ValType.Any;
Jump isString = new Jump(), afterSetFunctionName = new Jump();
mv.dup();
mv.instanceOf(Types.String);
mv.ifeq(isString);
{
// stack: [propertyKey, function, function, propertyKey] -> [propertyKey, function]
mv.checkcast(Types.String);
mv.invoke(Methods.OrdinaryFunction_SetFunctionName_String);
mv.goTo(afterSetFunctionName);
}
{
mv.mark(isString);
mv.checkcast(Types.Symbol);
mv.invoke(Methods.OrdinaryFunction_SetFunctionName_Symbol);
}
mv.mark(afterSetFunctionName);
}
if (hasOwnName != null) {
mv.mark(hasOwnName);
}
}
use of com.github.anba.es6draft.compiler.assembler.Jump 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);
}
}
}
Aggregations