use of com.github.anba.es6draft.runtime.ExecutionContext 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.ExecutionContext in project es6draft by anba.
the class InterpretedScriptBody method scriptEvaluation.
/**
* 15.1.7 Runtime Semantics: ScriptEvaluation
*
* @param cx
* the execution context
* @param script
* the script object
* @return the script evaluation result
*/
private Object scriptEvaluation(ExecutionContext cx, Script script) {
Realm realm = cx.getRealm();
/* step 1 (not applicable) */
/* step 2 */
LexicalEnvironment<GlobalEnvironmentRecord> globalEnv = realm.getGlobalEnv();
/* steps 3-7 */
ExecutionContext scriptCxt = newScriptExecutionContext(realm, script);
/* steps 8-9 */
ExecutionContext oldScriptContext = realm.getScriptContext();
try {
realm.setScriptContext(scriptCxt);
/* step 10 */
GlobalDeclarationInstantiation(scriptCxt, parsedScript, globalEnv);
/* steps 11-12 */
Object result = parsedScript.accept(new Interpreter(parsedScript), scriptCxt);
/* step 16 */
return result;
} finally {
/* steps 13-15 */
realm.setScriptContext(oldScriptContext);
}
}
use of com.github.anba.es6draft.runtime.ExecutionContext in project es6draft by anba.
the class Properties method getInstanceMethodHandle.
private static <OWNER> MethodHandle getInstanceMethodHandle(ExecutionContext cx, Converter converter, MethodHandle unreflect, OWNER owner) {
// var-args collector flag is not preserved when applying method handle combinators
boolean varargs = unreflect.isVarargsCollector();
MethodHandle handle = unreflect.bindTo(owner);
boolean callerContext = isCallerSensitive(handle);
final int fixedArguments = callerContext ? 1 : 0;
handle = bindContext(handle, cx);
handle = convertArguments(handle, fixedArguments, varargs, converter);
handle = convertReturn(handle, converter);
handle = catchExceptions(handle, converter);
handle = toCanonical(handle, fixedArguments, varargs, null);
if (!callerContext) {
handle = MethodHandles.dropArguments(handle, 0, ExecutionContext.class, Object.class);
} else {
handle = MethodHandles.dropArguments(handle, 1, Object.class);
}
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Object.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == Object.class;
return handle;
}
use of com.github.anba.es6draft.runtime.ExecutionContext in project es6draft by anba.
the class Properties method getStaticMethodHandle.
private static MethodHandle getStaticMethodHandle(ExecutionContext cx, Converter converter, MethodHandle unreflect, MethodKind methodKind) {
// var-args collector flag is not preserved when applying method handle combinators
boolean varargs = unreflect.isVarargsCollector();
MethodHandle handle = unreflect;
boolean callerContext = isCallerSensitive(handle);
final int fixedArguments = callerContext ? 2 : 1;
final int constructorArgument = callerContext ? 1 : 0;
handle = bindContext(handle, cx);
if (methodKind == MethodKind.Default) {
handle = convertThis(handle, callerContext, converter);
} else if (methodKind == MethodKind.Call) {
handle = MethodHandles.insertArguments(handle, constructorArgument, (Constructor) null);
handle = convertThis(handle, callerContext, converter);
} else {
assert methodKind == MethodKind.Construct;
handle = MethodHandles.insertArguments(handle, constructorArgument + 1, (Object) null);
}
handle = convertArguments(handle, fixedArguments, varargs, converter);
if (methodKind != MethodKind.Construct) {
handle = convertReturn(handle, converter);
} else {
handle = convertConstructReturn(handle, converter);
}
handle = catchExceptions(handle, converter);
handle = toCanonical(handle, fixedArguments, varargs, null);
if (!callerContext) {
handle = MethodHandles.dropArguments(handle, 0, ExecutionContext.class);
}
if (methodKind != MethodKind.Construct) {
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Object.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == Object.class;
} else {
assert handle.type().parameterCount() == 3;
assert handle.type().parameterType(0) == ExecutionContext.class;
assert handle.type().parameterType(1) == Constructor.class;
assert handle.type().parameterType(2) == Object[].class;
assert handle.type().returnType() == ScriptObject.class;
}
return handle;
}
use of com.github.anba.es6draft.runtime.ExecutionContext in project es6draft by anba.
the class NodeFunctions method createRequireFunction.
/**
* Creates a new {@code require()} function bound to the module record.
*
* @param module
* the module record
* @return the require function
*/
public static Callable createRequireFunction(ModuleRecord module) {
ExecutionContext cx = module.getRealm().defaultContext();
SourceIdentifier sourceId = module.getSourceCodeId();
Callable requireFn = createFunction(cx, new RequireFunction(sourceId), RequireFunction.class);
Callable resolveFn = createFunction(cx, new ResolveFunction(sourceId), ResolveFunction.class);
CreateDataProperty(cx, requireFn, "resolve", resolveFn);
return requireFn;
}
Aggregations