Skip to content

Commit

Permalink
Support implicit type coercion errors in es5-shim (#2917)
Browse files Browse the repository at this point in the history
* Support implicit type coercion errors in es5-shim

* Make the check even more specific
  • Loading branch information
lukastaegert committed Jun 10, 2019
1 parent 1718faa commit b377163
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/ast/nodes/BinaryExpression.ts
@@ -1,7 +1,11 @@
import { DeoptimizableEntity } from '../DeoptimizableEntity';
import { ExecutionPathOptions } from '../ExecutionPathOptions';
import { ImmutableEntityPathTracker } from '../utils/ImmutableEntityPathTracker';
import {
EMPTY_IMMUTABLE_TRACKER,
ImmutableEntityPathTracker
} from '../utils/ImmutableEntityPathTracker';
import { EMPTY_PATH, LiteralValueOrUnknown, ObjectPath, UNKNOWN_VALUE } from '../values';
import ExpressionStatement from './ExpressionStatement';
import { LiteralValue } from './Literal';
import * as NodeType from './NodeType';
import { ExpressionNode, NodeBase } from './shared/Node';
Expand Down Expand Up @@ -36,12 +40,14 @@ const binaryOperators: {
'|': (left: any, right: any) => left | right
};

export default class BinaryExpression extends NodeBase {
export default class BinaryExpression extends NodeBase implements DeoptimizableEntity {
left!: ExpressionNode;
operator!: keyof typeof binaryOperators;
right!: ExpressionNode;
type!: NodeType.tBinaryExpression;

deoptimizeCache(): void {}

getLiteralValueAtPath(
path: ObjectPath,
recursionTracker: ImmutableEntityPathTracker,
Expand All @@ -60,6 +66,18 @@ export default class BinaryExpression extends NodeBase {
return operatorFn(leftValue as LiteralValue, rightValue as LiteralValue);
}

hasEffects(options: ExecutionPathOptions): boolean {
// support some implicit type coercion runtime errors
if (
this.operator === '+' &&
this.parent instanceof ExpressionStatement &&
this.left.getLiteralValueAtPath(EMPTY_PATH, EMPTY_IMMUTABLE_TRACKER, this) === ''
) {
return true;
}
return super.hasEffects(options);
}

hasEffectsWhenAccessedAtPath(path: ObjectPath, _options: ExecutionPathOptions) {
return path.length > 1;
}
Expand Down
4 changes: 4 additions & 0 deletions test/form/samples/deopt-string-concatenation/_config.js
@@ -0,0 +1,4 @@
module.exports = {
description:
'deoptimize concatenation when used as an expression statement to better support es5-shim'
};
11 changes: 11 additions & 0 deletions test/form/samples/deopt-string-concatenation/_expected.js
@@ -0,0 +1,11 @@
function parseInt(str, radix) {
if (typeof str === 'symbol') {
'' + str;
}

var string = trim(String(str));
var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
return origParseInt(string, defaultedRadix);
}

console.log(parseInt('1'));
11 changes: 11 additions & 0 deletions test/form/samples/deopt-string-concatenation/main.js
@@ -0,0 +1,11 @@
function parseInt(str, radix) {
if (typeof str === 'symbol') {
'' + str;
}

var string = trim(String(str));
var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
return origParseInt(string, defaultedRadix);
}

console.log(parseInt('1'));

0 comments on commit b377163

Please sign in to comment.