mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-10-26 23:32:02 +03:00
Fix problem with stack location entries (#2183)
Summary: Release note: Improve source location information Changes to make sure that the source location of the call expression appears in the corresponding execution context record. Also emit execution records with no source location from stack traces. These are due to calls to internal helper methods for iterating over objects and arrays for argument destructuring. Finally fix a CompilerDiagnostic construction call to include a source location. Closes https://github.com/facebook/prepack/pull/2183 Differential Revision: D8698271 Pulled By: hermanventer fbshipit-source-id: 10f77f718db645a4784723c3eca4bd4e06eb43f8
This commit is contained in:
parent
0e09f6f986
commit
3deb5e2885
@ -50,12 +50,16 @@ export default function(
|
||||
}
|
||||
|
||||
// ECMA262 12.3.4.1
|
||||
realm.setNextExecutionContextLocation(ast.loc);
|
||||
|
||||
// 1. Let ref be the result of evaluating MemberExpression.
|
||||
let ref = env.evaluate(ast.callee, strictCode);
|
||||
|
||||
return evaluateReference(ref, ast, strictCode, env, realm);
|
||||
let previousLoc = realm.setNextExecutionContextLocation(ast.loc);
|
||||
try {
|
||||
return evaluateReference(ref, ast, strictCode, env, realm);
|
||||
} finally {
|
||||
realm.setNextExecutionContextLocation(previousLoc);
|
||||
}
|
||||
}
|
||||
|
||||
function evaluateReference(
|
||||
|
@ -28,8 +28,6 @@ export default function(
|
||||
env: LexicalEnvironment,
|
||||
realm: Realm
|
||||
): ObjectValue | AbstractObjectValue {
|
||||
realm.setNextExecutionContextLocation(ast.loc);
|
||||
|
||||
// ECMA262 12.3.3.1 We just implement this method inline since it's only called here.
|
||||
// 1. Return ? EvaluateNew(NewExpression, empty).
|
||||
|
||||
@ -62,12 +60,17 @@ export default function(
|
||||
// b. ReturnIfAbrupt(argList).
|
||||
}
|
||||
|
||||
// If we are in pure scope, attempt to recover from creating the construct if
|
||||
// it fails by creating a temporal abstract
|
||||
if (realm.isInPureScope()) {
|
||||
return tryToEvaluateConstructOrLeaveAsAbstract(constructor, argsList, strictCode, realm);
|
||||
} else {
|
||||
return createConstruct(constructor, argsList, realm);
|
||||
let previousLoc = realm.setNextExecutionContextLocation(ast.loc);
|
||||
try {
|
||||
// If we are in pure scope, attempt to recover from creating the construct if
|
||||
// it fails by creating a temporal abstract
|
||||
if (realm.isInPureScope()) {
|
||||
return tryToEvaluateConstructOrLeaveAsAbstract(constructor, argsList, strictCode, realm);
|
||||
} else {
|
||||
return createConstruct(constructor, argsList, realm);
|
||||
}
|
||||
} finally {
|
||||
realm.setNextExecutionContextLocation(previousLoc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ function buildStack(realm: Realm, context: ObjectValue) {
|
||||
|
||||
for (let executionContext of stack.reverse()) {
|
||||
let caller = executionContext.caller;
|
||||
if (!executionContext.loc) continue; // compiler generated helper for destructuring arguments
|
||||
let locString = describeLocation(
|
||||
realm,
|
||||
caller ? caller.function : undefined,
|
||||
|
@ -15,7 +15,6 @@ import { FatalError } from "../errors.js";
|
||||
import type { Realm } from "../realm.js";
|
||||
import type { ECMAScriptFunctionValue } from "../values/index.js";
|
||||
import { Completion, ReturnCompletion, AbruptCompletion, NormalCompletion } from "../completions.js";
|
||||
import { ExecutionContext } from "../realm.js";
|
||||
import { GlobalEnvironmentRecord, ObjectEnvironmentRecord } from "../environment.js";
|
||||
import {
|
||||
AbstractValue,
|
||||
@ -1044,7 +1043,7 @@ export class FunctionImplementation {
|
||||
ctx.suspend();
|
||||
|
||||
// 13. Let evalCxt be a new ECMAScript code execution context.
|
||||
let evalCxt = new ExecutionContext();
|
||||
let evalCxt = realm.createExecutionContext();
|
||||
evalCxt.isStrict = strictEval;
|
||||
|
||||
// 14. Set the evalCxt's Function to null.
|
||||
|
@ -30,8 +30,6 @@ export default function(
|
||||
env: LexicalEnvironment,
|
||||
realm: Realm
|
||||
): [Completion | Value, BabelNodeExpression, Array<BabelNodeStatement>] {
|
||||
realm.setNextExecutionContextLocation(ast.loc);
|
||||
|
||||
// 1. Let ref be the result of evaluating MemberExpression.
|
||||
let [ref, calleeAst, calleeIO] = env.partiallyEvaluateCompletion(ast.callee, strictCode);
|
||||
if (ref instanceof AbruptCompletion) return [ref, (calleeAst: any), calleeIO];
|
||||
@ -70,23 +68,28 @@ export default function(
|
||||
}
|
||||
}
|
||||
|
||||
let callResult = EvaluateCall(ref, func, ast, argVals, strictCode, env, realm);
|
||||
if (callResult instanceof AbruptCompletion) {
|
||||
if (completion instanceof PossiblyNormalCompletion)
|
||||
completion = Join.stopEffectCaptureJoinApplyAndReturnCompletion(completion, callResult, realm);
|
||||
else completion = callResult;
|
||||
let resultAst = t.callExpression((calleeAst: any), partialArgs);
|
||||
return [completion, resultAst, io];
|
||||
let previousLoc = realm.setNextExecutionContextLocation(ast.loc);
|
||||
try {
|
||||
let callResult = EvaluateCall(ref, func, ast, argVals, strictCode, env, realm);
|
||||
if (callResult instanceof AbruptCompletion) {
|
||||
if (completion instanceof PossiblyNormalCompletion)
|
||||
completion = Join.stopEffectCaptureJoinApplyAndReturnCompletion(completion, callResult, realm);
|
||||
else completion = callResult;
|
||||
let resultAst = t.callExpression((calleeAst: any), partialArgs);
|
||||
return [completion, resultAst, io];
|
||||
}
|
||||
let callCompletion;
|
||||
[callCompletion, callResult] = Join.unbundleNormalCompletion(callResult);
|
||||
invariant(callResult instanceof Value);
|
||||
invariant(completion === undefined || completion instanceof PossiblyNormalCompletion);
|
||||
completion = Join.composeNormalCompletions(completion, callCompletion, callResult, realm);
|
||||
if (completion instanceof PossiblyNormalCompletion) {
|
||||
realm.captureEffects(completion);
|
||||
}
|
||||
return [completion, t.callExpression((calleeAst: any), partialArgs), io];
|
||||
} finally {
|
||||
realm.setNextExecutionContextLocation(previousLoc);
|
||||
}
|
||||
let callCompletion;
|
||||
[callCompletion, callResult] = Join.unbundleNormalCompletion(callResult);
|
||||
invariant(callResult instanceof Value);
|
||||
invariant(completion === undefined || completion instanceof PossiblyNormalCompletion);
|
||||
completion = Join.composeNormalCompletions(completion, callCompletion, callResult, realm);
|
||||
if (completion instanceof PossiblyNormalCompletion) {
|
||||
realm.captureEffects(completion);
|
||||
}
|
||||
return [completion, t.callExpression((calleeAst: any), partialArgs), io];
|
||||
}
|
||||
|
||||
function callBothFunctionsAndJoinTheirEffects(
|
||||
|
14
src/realm.js
14
src/realm.js
@ -1617,26 +1617,18 @@ export class Realm {
|
||||
|
||||
createExecutionContext(): ExecutionContext {
|
||||
let context = new ExecutionContext();
|
||||
|
||||
let loc = this.nextContextLocation;
|
||||
if (loc) {
|
||||
context.setLocation(loc);
|
||||
this.nextContextLocation = null;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
setNextExecutionContextLocation(loc: ?BabelNodeSourceLocation) {
|
||||
if (!loc) return;
|
||||
|
||||
//if (this.nextContextLocation) {
|
||||
// throw new ThrowCompletion(
|
||||
// Construct(this, this.intrinsics.TypeError, [new StringValue(this, "Already have a context location that we haven't used yet")])
|
||||
// );
|
||||
//} else {
|
||||
setNextExecutionContextLocation(loc: ?BabelNodeSourceLocation): ?BabelNodeSourceLocation {
|
||||
let previousValue = this.nextContextLocation;
|
||||
this.nextContextLocation = loc;
|
||||
//}
|
||||
return previousValue;
|
||||
}
|
||||
|
||||
reportIntrospectionError(message?: void | string | StringValue) {
|
||||
|
@ -84,7 +84,7 @@ export class Functions {
|
||||
realm.handleError(
|
||||
new CompilerDiagnostic(
|
||||
`Optimized Function Value ${location} is an not a function or react element`,
|
||||
undefined,
|
||||
realm.currentLocation,
|
||||
"PP0033",
|
||||
"FatalError"
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// expected errors: [{"location":{"start":{"line":7,"column":16},"end":{"line":7,"column":18},"source":"test/error-handler/FinalObjectCannotBeMutated.js"},"severity":"FatalError","errorCode":"PP0026","callStack":"Error\n at f (unknown)"}]
|
||||
// expected errors: [{"location":{"start":{"line":7,"column":16},"end":{"line":7,"column":18},"source":"test/error-handler/FinalObjectCannotBeMutated.js"},"severity":"FatalError","errorCode":"PP0026","callStack":"Error\n "}]
|
||||
(function () {
|
||||
function f() {
|
||||
let o = {};
|
||||
|
Loading…
Reference in New Issue
Block a user