use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.
the class FunctionCodeGenerator method generateLegacyFunctionConstruct.
/**
* Generate bytecode for:
*
* <pre>
* oldCaller = function.getLegacyCaller()
* oldArguments = function.getLegacyArguments()
* function.setLegacyCaller(callerContext.getCurrentFunction())
* try {
* thisArgument = OrdinaryCreateFromConstructor(callerContext, newTarget, %ObjectPrototype%)
* calleeContext = newFunctionExecutionContext(function, newTarget, thisArgument)
* result = OrdinaryCallEvaluateBody(function, argumentsList)
* return returnResultOrThis(result)
* } finally {
* function.restoreLegacyProperties(oldCaller, oldArguments)
* }
* </pre>
*
* @param node
* the function node
* @param mv
* the instruction visitor
*/
private void generateLegacyFunctionConstruct(FunctionNode node, InstructionVisitor mv) {
final boolean hasArguments = codegen.isEnabled(CompatibilityOption.FunctionArguments);
final boolean hasCaller = codegen.isEnabled(CompatibilityOption.FunctionCaller);
Variable<LegacyConstructorFunction> function = mv.getParameter(FUNCTION, LegacyConstructorFunction.class);
Variable<ExecutionContext> callerContext = mv.getParameter(EXECUTION_CONTEXT, ExecutionContext.class);
Variable<Constructor> newTarget = mv.getParameter(NEW_TARGET, Constructor.class);
Variable<Object[]> arguments = mv.getParameter(ARGUMENTS, Object[].class);
Variable<ScriptObject> thisArg = mv.newVariable("thisArgument", ScriptObject.class);
Variable<ExecutionContext> calleeContext = mv.newVariable("calleeContext", ExecutionContext.class);
Variable<FunctionObject> oldCaller = mv.newVariable("oldCaller", FunctionObject.class);
Variable<LegacyConstructorFunction.Arguments> oldArguments = mv.newVariable("oldArguments", LegacyConstructorFunction.Arguments.class);
Variable<Throwable> throwable = mv.newVariable("throwable", Throwable.class);
// (1) Retrieve 'caller' and 'arguments' and store in local variables
if (hasCaller) {
mv.load(function);
mv.invoke(Methods.LegacyConstructorFunction_getLegacyCaller);
} else {
mv.anull();
}
mv.store(oldCaller);
if (hasArguments) {
mv.load(function);
mv.invoke(Methods.LegacyConstructorFunction_getLegacyArguments);
} else {
mv.anull();
}
mv.store(oldArguments);
// (2) Update 'caller' and 'arguments' properties
if (hasCaller) {
setLegacyCaller(function, callerContext, mv);
}
if (hasArguments) {
setLegacyArguments(function, arguments, mv);
}
TryCatchLabel startFinally = new TryCatchLabel(), endFinally = new TryCatchLabel();
TryCatchLabel handlerFinally = new TryCatchLabel();
mv.mark(startFinally);
{
// (3) Create this-argument
ordinaryCreateFromConstructor(callerContext, newTarget, thisArg, mv);
// (4) Create a new ExecutionContext
prepareCallAndBindThis(node, calleeContext, function, newTarget, thisArg, mv);
// (5) Call OrdinaryCallEvaluateBody
ordinaryCallEvaluateBody(node, calleeContext, function, arguments, mv);
// (6) Restore 'caller' and 'arguments'
restoreLegacyProperties(function, oldCaller, oldArguments, mv);
// (7) Return result value
returnResultOrThis(thisArg, false, mv);
}
mv.mark(endFinally);
// Exception: Restore 'caller' and 'arguments' and then rethrow exception
mv.finallyHandler(handlerFinally);
mv.store(throwable);
restoreLegacyProperties(function, oldCaller, oldArguments, mv);
mv.load(throwable);
mv.athrow();
mv.tryFinally(startFinally, endFinally, handlerFinally);
}
use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction 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 source
* the source object
* @param function
* the compiled function
* @param newTarget
* the newTarget constructor function
* @param fallbackProto
* the fallback prototype
* @return the new function object
*/
private static FunctionObject CreateDynamicFunction(ExecutionContext cx, Source source, RuntimeInfo.Function function, Constructor newTarget, Intrinsics fallbackProto) {
/* steps 1-11, 13-20 (not applicable) */
/* step 12 */
boolean strict = function.isStrict();
/* steps 21-22 */
ScriptObject proto = GetPrototypeFromConstructor(cx, newTarget, fallbackProto);
/* step 23 */
FunctionObject f;
if (function.is(RuntimeInfo.FunctionFlags.Legacy)) {
assert !strict;
f = LegacyConstructorFunction.FunctionAllocate(cx, proto);
} else {
f = FunctionAllocate(cx, proto, strict, FunctionKind.Normal, ConstructorKind.Base);
}
/* steps 24-25 */
LexicalEnvironment<GlobalEnvironmentRecord> scope = f.getRealm().getGlobalEnv();
/* step 26 */
FunctionInitialize(f, FunctionKind.Normal, function, scope, newFunctionExecutable(source));
// Work around for: https://bugs.eclipse.org/bugs/show_bug.cgi?id=479802
if (f instanceof LegacyConstructorFunction) {
MakeConstructor(cx, (LegacyConstructorFunction) f);
} else {
MakeConstructor(cx, (OrdinaryConstructorFunction) f);
}
/* step 29 */
SetFunctionName(f, "anonymous");
/* step 30 */
return f;
}
use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.
the class FunctionOperations method EvaluateLegacyFunctionExpression.
/**
* 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 LegacyConstructorFunction EvaluateLegacyFunctionExpression(RuntimeInfo.Function fd, ExecutionContext cx) {
LegacyConstructorFunction closure;
if (!fd.is(RuntimeInfo.FunctionFlags.ScopedName)) {
/* step 1 (not applicable) */
/* step 2 */
LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
/* step 3 */
closure = LegacyFunctionCreate(cx, 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 = LegacyFunctionCreate(cx, fd, funcEnv);
/* step 8 */
MakeConstructor(cx, closure);
/* step 9 */
SetFunctionName(closure, name);
/* step 10 */
envRec.initializeBinding(name, closure);
}
/* step 5/11 */
return closure;
}
use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.
the class FunctionOperations method InstantiateLegacyFunctionObject.
/**
* 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 LegacyConstructorFunction InstantiateLegacyFunctionObject(LexicalEnvironment<?> scope, ExecutionContext cx, RuntimeInfo.Function fd) {
/* step 1 (not applicable) */
/* step 2 */
String name = fd.functionName();
/* step 3 */
LegacyConstructorFunction f = LegacyFunctionCreate(cx, 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.LegacyConstructorFunction 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;
}
Aggregations