Commit 0e53739c authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Add lint errors for unused variable and label bindings

This CL adds lint errors when 'let' bindings, arguments and labels
are not used. Note that errors for 'const' bindings will be added
later.

In cases where arguments are actually needed to match the signature,
the warning can be silenced by prefixing identifiers with "_". This
might be needed for generic specializations or builtins called from
TurboFan. Trying to use a variable or label that was marked with
"_" results in a compilation error.

Implicit arguments are not linted. They are implemented using exact
string matching. Prefixing an implicit argument with "_" in a callee
would break all callers as the names would no longer match.

Drive-by: Fix all new lint errors in the existing Torque code.

Bug: v8:7793
Change-Id: I68b3c59c76b956e9f88709e9388a40a19546ce52
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1645092
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62027}
parent 35253de7
......@@ -51,9 +51,9 @@ namespace array {
}
transitioning builtin ArrayEveryLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
array: Object, o: JSReceiver, initialK: Number, length: Number,
initialTo: Object): Object {
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_array: Object, o: JSReceiver, initialK: Number, length: Number,
_initialTo: Object): Object {
// 5. Let k be 0.
// 6. Repeat, while k < len
for (let k: Number = initialK; k < length; k++) {
......
......@@ -58,7 +58,7 @@ namespace array_filter {
}
transitioning builtin ArrayFilterLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
array: JSReceiver, o: JSReceiver, initialK: Number, length: Number,
initialTo: Number): Object {
let to: Number = initialTo;
......
......@@ -25,8 +25,8 @@ namespace array_find {
transitioning javascript builtin
ArrayFindLoopLazyDeoptContinuation(implicit context: Context)(
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
length: Object, result: Object): Object {
_receiver: Object, _callback: Object, _thisArg: Object, _initialK: Object,
_length: Object, _result: Object): Object {
// This deopt continuation point is never actually called, it just
// exists to make stack traces correct from a ThrowTypeError if the
// callback was found to be non-callable.
......@@ -62,7 +62,7 @@ namespace array_find {
}
transitioning builtin ArrayFindLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
o: JSReceiver, initialK: Number, length: Number): Object {
// 5. Let k be 0.
// 6. Repeat, while k < len
......
......@@ -25,8 +25,8 @@ namespace array_findindex {
transitioning javascript builtin
ArrayFindIndexLoopLazyDeoptContinuation(implicit context: Context)(
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
length: Object, result: Object): Object {
_receiver: Object, _callback: Object, _thisArg: Object, _initialK: Object,
_length: Object, _result: Object): Object {
// This deopt continuation point is never actually called, it just
// exists to make stack traces correct from a ThrowTypeError if the
// callback was found to be non-callable.
......@@ -64,7 +64,7 @@ namespace array_findindex {
transitioning builtin ArrayFindIndexLoopContinuation(implicit context:
Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
o: JSReceiver, initialK: Number, length: Number): Number {
// 5. Let k be 0.
// 6. Repeat, while k < len
......
......@@ -23,7 +23,7 @@ namespace array_foreach {
transitioning javascript builtin
ArrayForEachLoopLazyDeoptContinuation(implicit context: Context)(
receiver: Object, callback: Object, thisArg: Object, initialK: Object,
length: Object, result: Object): Object {
length: Object, _result: Object): Object {
// All continuation points in the optimized forEach implemntation are
// after the ToObject(O) call that ensures we are dealing with a
// JSReceiver.
......@@ -38,9 +38,9 @@ namespace array_foreach {
}
transitioning builtin ArrayForEachLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
array: Object, o: JSReceiver, initialK: Number, len: Number,
to: Object): Object {
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_array: Object, o: JSReceiver, initialK: Number, len: Number,
_to: Object): Object {
// variables {array} and {to} are ignored.
// 5. Let k be 0.
......
......@@ -103,8 +103,8 @@ namespace array_join {
}
CannotUseSameArrayAccessor<JSTypedArray>(implicit context: Context)(
loadFn: LoadJoinElementFn, receiver: JSReceiver, initialMap: Map,
initialLen: Number): never
_loadFn: LoadJoinElementFn, receiver: JSReceiver, _initialMap: Map,
_initialLen: Number): never
labels Cannot, Can {
const typedArray: JSTypedArray = UnsafeCast<JSTypedArray>(receiver);
if (IsDetachedBuffer(typedArray.buffer)) goto Cannot;
......@@ -246,7 +246,7 @@ namespace array_join {
case (nofSeparators: Number): {
return StringRepeat(context, sep, nofSeparators);
}
case (obj: Object): {
case (Object): {
unreachable;
}
}
......
......@@ -55,7 +55,7 @@ namespace array_map {
}
transitioning builtin ArrayMapLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
array: JSReceiver, o: JSReceiver, initialK: Number,
length: Number): Object {
// 6. Let k be 0.
......@@ -226,7 +226,7 @@ namespace array_map {
macro FastMapSpeciesCreate(implicit context: Context)(
receiver: JSReceiver, length: Number): JSArray labels Bailout {
if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
const o = Cast<FastJSArray>(receiver) otherwise Bailout;
Cast<FastJSArray>(receiver) otherwise Bailout;
const smiLength = Cast<Smi>(length) otherwise Bailout;
const newMap: Map =
LoadJSArrayElementsMap(PACKED_SMI_ELEMENTS, LoadNativeContext(context));
......
......@@ -64,8 +64,8 @@ namespace array {
transitioning builtin ArrayReduceRightLoopContinuation(implicit context:
Context)(
receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object,
o: JSReceiver, initialK: Number, length: Number): Object {
_receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object,
o: JSReceiver, initialK: Number, _length: Number): Object {
let accumulator = initialAccumulator;
// 8b and 9. Repeat, while k >= 0
......
......@@ -63,7 +63,7 @@ namespace array {
}
transitioning builtin ArrayReduceLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object,
_receiver: JSReceiver, callbackfn: Callable, initialAccumulator: Object,
o: JSReceiver, initialK: Number, length: Number): Object {
let accumulator = initialAccumulator;
......@@ -110,7 +110,7 @@ namespace array {
labels Bailout(Number, Object) {
const k = 0;
let accumulator = initialAccumulator;
const smiLen = Cast<Smi>(len) otherwise goto Bailout(k, accumulator);
Cast<Smi>(len) otherwise goto Bailout(k, accumulator);
let fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k, accumulator);
let fastOW = NewFastJSArrayWitness(fastO);
......
......@@ -105,7 +105,6 @@ namespace array_slice {
return ExtractFastJSArray(context, a, start, count);
}
case (a: JSArgumentsObjectWithLength): {
const nativeContext: NativeContext = LoadNativeContext(context);
const map: Map = a.map;
if (IsFastAliasedArgumentsMap(map)) {
return HandleFastAliasedSloppyArgumentsSlice(context, a, start, count)
......
......@@ -51,9 +51,9 @@ namespace array {
}
transitioning builtin ArraySomeLoopContinuation(implicit context: Context)(
receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
array: Object, o: JSReceiver, initialK: Number, length: Number,
initialTo: Object): Object {
_receiver: JSReceiver, callbackfn: Callable, thisArg: Object,
_array: Object, o: JSReceiver, initialK: Number, length: Number,
_initialTo: Object): Object {
// 5. Let k be 0.
// 6. Repeat, while k < len
for (let k: Number = initialK; k < length; k++) {
......
......@@ -54,8 +54,7 @@ namespace array_splice {
macro FastSplice<FixedArrayType: type, ElementType: type>(implicit context:
Context)(
args: Arguments, a: JSArray, length: Smi, newLength: Smi,
lengthDelta: Smi, actualStart: Smi, insertCount: Smi,
actualDeleteCount: Smi): void labels Bailout {
actualStart: Smi, insertCount: Smi, actualDeleteCount: Smi): void {
// Make sure elements are writable.
array::EnsureWriteableFastElements(a);
......@@ -168,12 +167,12 @@ namespace array_splice {
if (IsFastSmiOrTaggedElementsKind(elementsKind)) {
FastSplice<FixedArray, Object>(
args, a, length, newLength, lengthDelta, actualStart, insertCount,
actualDeleteCount) otherwise Bailout;
args, a, length, newLength, actualStart, insertCount,
actualDeleteCount);
} else {
FastSplice<FixedDoubleArray, Number>(
args, a, length, newLength, lengthDelta, actualStart, insertCount,
actualDeleteCount) otherwise Bailout;
args, a, length, newLength, actualStart, insertCount,
actualDeleteCount);
}
return deletedResult;
......@@ -301,8 +300,6 @@ namespace array_splice {
context: Context, arguments: Arguments, o: JSReceiver, len: Number,
actualStart: Number, insertCount: Smi,
actualDeleteCount: Number): Object {
const affected: Number = len - actualStart - actualDeleteCount;
// 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
const a: JSReceiver = ArraySpeciesCreate(context, o, actualDeleteCount);
const itemCount: Number = insertCount;
......
......@@ -33,12 +33,13 @@ namespace array {
}
macro IsJSArray(implicit context: Context)(o: Object): bool {
try {
const array: JSArray = Cast<JSArray>(o) otherwise NotArray;
return true;
}
label NotArray {
return false;
typeswitch (o) {
case (JSArray): {
return true;
}
case (Object): {
return false;
}
}
}
......
......@@ -411,12 +411,12 @@ macro NewJSArray(implicit context: Context)(): JSArray {
}
struct HoleIterator {
Next(): Object labels NoMore() {
Next(): Object labels _NoMore {
return Hole;
}
}
macro NewJSArray(implicit context: Context)(map: Map, length: Smi): JSArray {
macro NewJSArray(implicit context: Context)(_map: Map, length: Smi): JSArray {
const map = GetFastPackedSmiElementsJSArrayMap();
const i = HoleIterator{};
const elements = new FixedArray{map, length, objects: ...i};
......@@ -1770,7 +1770,7 @@ macro Cast<A: type>(o: HeapObject): A
labels CastError;
Cast<HeapObject>(o: HeapObject): HeapObject
labels CastError {
labels _CastError {
return o;
}
......@@ -1972,24 +1972,24 @@ Cast<FastJSArrayForCopy>(implicit context: Context)(o: HeapObject):
FastJSArrayForCopy
labels CastError {
if (IsArraySpeciesProtectorCellInvalid()) goto CastError;
const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError;
return %RawDownCast<FastJSArrayForCopy>(o);
const a = Cast<FastJSArray>(o) otherwise CastError;
return %RawDownCast<FastJSArrayForCopy>(a);
}
Cast<FastJSArrayWithNoCustomIteration>(implicit context: Context)(
o: HeapObject): FastJSArrayWithNoCustomIteration
labels CastError {
if (IsArrayIteratorProtectorCellInvalid()) goto CastError;
const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError;
return %RawDownCast<FastJSArrayWithNoCustomIteration>(o);
const a = Cast<FastJSArray>(o) otherwise CastError;
return %RawDownCast<FastJSArrayWithNoCustomIteration>(a);
}
Cast<FastJSArrayForReadWithNoCustomIteration>(implicit context: Context)(
o: HeapObject): FastJSArrayForReadWithNoCustomIteration
labels CastError {
if (IsArrayIteratorProtectorCellInvalid()) goto CastError;
const a: FastJSArrayForRead = Cast<FastJSArrayForRead>(o) otherwise CastError;
return %RawDownCast<FastJSArrayForReadWithNoCustomIteration>(o);
const a = Cast<FastJSArrayForRead>(o) otherwise CastError;
return %RawDownCast<FastJSArrayForReadWithNoCustomIteration>(a);
}
Cast<JSReceiver>(implicit context: Context)(o: HeapObject): JSReceiver
......
......@@ -33,7 +33,7 @@ namespace collections {
}
}
}
case (receiver: JSReceiver): {
case (JSReceiver): {
goto MayHaveSideEffects;
}
case (o: Object): deferred {
......
......@@ -7,7 +7,7 @@ namespace math {
extern macro Float64Acos(float64): float64;
transitioning javascript builtin
MathAcos(context: Context, receiver: Object, x: Object): Number {
MathAcos(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Acos(value));
}
......@@ -16,7 +16,7 @@ namespace math {
extern macro Float64Acosh(float64): float64;
transitioning javascript builtin
MathAcosh(context: Context, receiver: Object, x: Object): Number {
MathAcosh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Acosh(value));
}
......@@ -25,7 +25,7 @@ namespace math {
extern macro Float64Asin(float64): float64;
transitioning javascript builtin
MathAsin(context: Context, receiver: Object, x: Object): Number {
MathAsin(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Asin(value));
}
......@@ -34,7 +34,7 @@ namespace math {
extern macro Float64Asinh(float64): float64;
transitioning javascript builtin
MathAsinh(context: Context, receiver: Object, x: Object): Number {
MathAsinh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Asinh(value));
}
......@@ -43,7 +43,7 @@ namespace math {
extern macro Float64Atan(float64): float64;
transitioning javascript builtin
MathAtan(context: Context, receiver: Object, x: Object): Number {
MathAtan(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Atan(value));
}
......@@ -52,7 +52,7 @@ namespace math {
extern macro Float64Atan2(float64, float64): float64;
transitioning javascript builtin
MathAtan2(context: Context, receiver: Object, y: Object, x: Object): Number {
MathAtan2(context: Context, _receiver: Object, y: Object, x: Object): Number {
const yValue = Convert<float64>(ToNumber_Inline(context, y));
const xValue = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Atan2(yValue, xValue));
......@@ -62,7 +62,7 @@ namespace math {
extern macro Float64Atanh(float64): float64;
transitioning javascript builtin
MathAtanh(context: Context, receiver: Object, x: Object): Number {
MathAtanh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Atanh(value));
}
......@@ -71,7 +71,7 @@ namespace math {
extern macro Float64Cbrt(float64): float64;
transitioning javascript builtin
MathCbrt(context: Context, receiver: Object, x: Object): Number {
MathCbrt(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Cbrt(value));
}
......@@ -80,7 +80,7 @@ namespace math {
extern macro Word32Clz(int32): int32;
transitioning javascript builtin
MathClz32(context: Context, receiver: Object, x: Object): Number {
MathClz32(context: Context, _receiver: Object, x: Object): Number {
const num = ToNumber_Inline(context, x);
let value: int32;
......@@ -100,7 +100,7 @@ namespace math {
extern macro Float64Cos(float64): float64;
transitioning javascript builtin
MathCos(context: Context, receiver: Object, x: Object): Number {
MathCos(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Cos(value));
}
......@@ -109,7 +109,7 @@ namespace math {
extern macro Float64Cosh(float64): float64;
transitioning javascript builtin
MathCosh(context: Context, receiver: Object, x: Object): Number {
MathCosh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Cosh(value));
}
......@@ -118,7 +118,7 @@ namespace math {
extern macro Float64Exp(float64): float64;
transitioning javascript builtin
MathExp(context: Context, receiver: Object, x: Object): Number {
MathExp(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Exp(value));
}
......@@ -127,14 +127,14 @@ namespace math {
extern macro Float64Expm1(float64): float64;
transitioning javascript builtin
MathExpm1(context: Context, receiver: Object, x: Object): Number {
MathExpm1(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Expm1(value));
}
// ES6 #sec-math.fround
transitioning javascript builtin
MathFround(context: Context, receiver: Object, x: Object): Number {
MathFround(context: Context, _receiver: Object, x: Object): Number {
const x32 = Convert<float32>(ToNumber_Inline(context, x));
const x64 = Convert<float64>(x32);
return Convert<Number>(x64);
......@@ -144,7 +144,7 @@ namespace math {
extern macro Float64Log(float64): float64;
transitioning javascript builtin
MathLog(context: Context, receiver: Object, x: Object): Number {
MathLog(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Log(value));
}
......@@ -153,7 +153,7 @@ namespace math {
extern macro Float64Log1p(float64): float64;
transitioning javascript builtin
MathLog1p(context: Context, receiver: Object, x: Object): Number {
MathLog1p(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Log1p(value));
}
......@@ -162,7 +162,7 @@ namespace math {
extern macro Float64Log10(float64): float64;
transitioning javascript builtin
MathLog10(context: Context, receiver: Object, x: Object): Number {
MathLog10(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Log10(value));
}
......@@ -171,7 +171,7 @@ namespace math {
extern macro Float64Log2(float64): float64;
transitioning javascript builtin
MathLog2(context: Context, receiver: Object, x: Object): Number {
MathLog2(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Log2(value));
}
......@@ -180,14 +180,14 @@ namespace math {
extern macro Float64Sin(float64): float64;
transitioning javascript builtin
MathSin(context: Context, receiver: Object, x: Object): Number {
MathSin(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Sin(value));
}
// ES6 #sec-math.sign
transitioning javascript builtin
MathSign(context: Context, receiver: Object, x: Object): Number {
MathSign(context: Context, _receiver: Object, x: Object): Number {
const num = ToNumber_Inline(context, x);
const value = Convert<float64>(num);
......@@ -204,7 +204,7 @@ namespace math {
extern macro Float64Sinh(float64): float64;
transitioning javascript builtin
MathSinh(context: Context, receiver: Object, x: Object): Number {
MathSinh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Sinh(value));
}
......@@ -213,7 +213,7 @@ namespace math {
extern macro Float64Sqrt(float64): float64;
transitioning javascript builtin
MathSqrt(context: Context, receiver: Object, x: Object): Number {
MathSqrt(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Sqrt(value));
}
......@@ -222,7 +222,7 @@ namespace math {
extern macro Float64Tan(float64): float64;
transitioning javascript builtin
MathTan(context: Context, receiver: Object, x: Object): Number {
MathTan(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Tan(value));
}
......@@ -231,7 +231,7 @@ namespace math {
extern macro Float64Tanh(float64): float64;
transitioning javascript builtin
MathTanh(context: Context, receiver: Object, x: Object): Number {
MathTanh(context: Context, _receiver: Object, x: Object): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Tanh(value));
}
......
......@@ -20,7 +20,7 @@ namespace object {
namespace object_isextensible {
// ES6 section 19.1.2.11 Object.isExtensible ( O )
transitioning javascript builtin ObjectIsExtensible(
implicit context: Context)(receiver: Object, object: Object): Object {
implicit context: Context)(_receiver: Object, object: Object): Object {
return object::ObjectIsExtensible(object);
}
} // namespace object-isextensible
......@@ -13,7 +13,7 @@ namespace proxy {
// https://tc39.github.io/ecma262/#sec-proxy-constructor
transitioning javascript builtin
ProxyConstructor(implicit context: Context)(
receiver: Object, target: Object, handler: Object): JSProxy {
_receiver: Object, target: Object, handler: Object): JSProxy {
try {
// 1. If NewTarget is undefined, throw a TypeError exception.
const newTarget: Object = GetProxyConstructorJSNewTarget();
......
......@@ -17,7 +17,7 @@ namespace proxy {
// https://tc39.github.io/ecma262/#sec-proxy.revocable
transitioning javascript builtin
ProxyRevocable(
context: Context, receiver: Object, target: Object,
context: Context, _receiver: Object, target: Object,
handler: Object): JSProxyRevocableResult {
try {
const targetJSReceiver =
......
......@@ -15,8 +15,7 @@ namespace proxy {
macro IsRevokedProxy(implicit context: Context)(o: JSReceiver): bool {
const proxy: JSProxy = Cast<JSProxy>(o) otherwise return false;
const handler: JSReceiver =
Cast<JSReceiver>(proxy.handler) otherwise return true;
Cast<JSReceiver>(proxy.handler) otherwise return true;
return false;
}
......
......@@ -72,8 +72,7 @@ namespace regexp_replace {
transitioning macro
RegExpReplaceCallableWithExplicitCaptures(implicit context: Context)(
matchesElements: FixedArray, matchesLength: intptr, string: String,
replaceFn: Callable) {
matchesElements: FixedArray, matchesLength: intptr, replaceFn: Callable) {
for (let i: intptr = 0; i < matchesLength; i++) {
const elArray =
Cast<JSArray>(matchesElements.objects[i]) otherwise continue;
......@@ -124,7 +123,7 @@ namespace regexp_replace {
matchesElements, matchesLengthInt, string, replaceFn);
} else {
RegExpReplaceCallableWithExplicitCaptures(
matchesElements, matchesLengthInt, string, replaceFn);
matchesElements, matchesLengthInt, replaceFn);
}
return StringBuilderConcat(matches, matchesLength, string);
......
......@@ -75,7 +75,7 @@ namespace string {
GenerateStringAt(receiver, position, 'String.prototype.charAt')
otherwise IfInBounds, IfOutOfBounds;
}
label IfInBounds(string: String, index: intptr, length: intptr) {
label IfInBounds(string: String, index: intptr, _length: intptr) {
const code: int32 = StringCharCodeAt(string, index);
return StringFromSingleCharCode(code);
}
......@@ -91,7 +91,7 @@ namespace string {
GenerateStringAt(receiver, position, 'String.prototype.charCodeAt')
otherwise IfInBounds, IfOutOfBounds;
}
label IfInBounds(string: String, index: intptr, length: intptr) {
label IfInBounds(string: String, index: intptr, _length: intptr) {
const code: int32 = StringCharCodeAt(string, index);
return Convert<Smi>(code);
}
......
......@@ -126,8 +126,7 @@ namespace typed_array_createtypedarray {
// 22.2.4.4 TypedArray ( object )
// ES #sec-typedarray-object
transitioning macro ConstructByIterable(implicit context: Context)(
typedArray: JSTypedArray, iterable: JSReceiver, iteratorFn: Callable,
elementsInfo: typed_array::TypedArrayElementsInfo): never
iterable: JSReceiver, iteratorFn: Callable): never
labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) {
const array: JSArray =
IterableToListMayPreserveHoles(context, iterable, iteratorFn);
......@@ -137,8 +136,7 @@ namespace typed_array_createtypedarray {
// 22.2.4.3 TypedArray ( typedArray )
// ES #sec-typedarray-typedarray
transitioning macro ConstructByTypedArray(implicit context: Context)(
typedArray: JSTypedArray, srcTypedArray: JSTypedArray,
elementsInfo: typed_array::TypedArrayElementsInfo): never
srcTypedArray: JSTypedArray): never
labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) {
let bufferConstructor: JSReceiver = GetArrayBufferFunction();
const srcBuffer: JSArrayBuffer = srcTypedArray.buffer;
......@@ -242,16 +240,15 @@ namespace typed_array_createtypedarray {
}
}
transitioning macro ConstructByJSReceiver(implicit context: Context)(
array: JSTypedArray, obj: JSReceiver,
elementsInfo: typed_array::TypedArrayElementsInfo): never
transitioning macro ConstructByJSReceiver(implicit context:
Context)(obj: JSReceiver): never
labels IfConstructByArrayLike(HeapObject, Object, JSReceiver) {
try {
const iteratorMethod: Object =
GetIteratorMethod(obj) otherwise IfIteratorUndefined;
const iteratorFn: Callable = Cast<Callable>(iteratorMethod)
otherwise ThrowTypeError(kIteratorSymbolNonCallable);
ConstructByIterable(array, obj, iteratorFn, elementsInfo)
ConstructByIterable(obj, iteratorFn)
otherwise IfConstructByArrayLike;
}
label IfIteratorUndefined {
......@@ -299,12 +296,10 @@ namespace typed_array_createtypedarray {
ConstructByArrayBuffer(array, buffer, arg2, arg3, elementsInfo);
}
case (typedArray: JSTypedArray): {
ConstructByTypedArray(array, typedArray, elementsInfo)
otherwise IfConstructByArrayLike;
ConstructByTypedArray(typedArray) otherwise IfConstructByArrayLike;
}
case (obj: JSReceiver): {
ConstructByJSReceiver(array, obj, elementsInfo)
otherwise IfConstructByArrayLike;
ConstructByJSReceiver(obj) otherwise IfConstructByArrayLike;
}
// The first argument was a number or fell through and is treated as
// a number. https://tc39.github.io/ecma262/#sec-typedarray-length
......
......@@ -201,7 +201,7 @@ namespace typed_array {
}
builtin LoadFixedElement<T: type>(
context: Context, array: JSTypedArray, index: Smi): Object {
_context: Context, array: JSTypedArray, index: Smi): Object {
return LoadFixedTypedArrayElementAsTagged(
array.data_ptr, index, KindForArrayType<T>(), SMI_PARAMETERS);
}
......
......@@ -142,6 +142,12 @@ struct AstNodeClassCheck {
struct Expression : AstNode {
Expression(Kind kind, SourcePosition pos) : AstNode(kind, pos) {}
DEFINE_AST_NODE_INNER_BOILERPLATE(Expression)
using VisitCallback = std::function<void(Expression*)>;
virtual void VisitAllSubExpressions(VisitCallback callback) {
// TODO(szuend): Hoist this up to AstNode and make it a
// general Ast visitor.
}
};
struct LocationExpression : Expression {
......@@ -226,6 +232,11 @@ struct IdentifierExpression : LocationExpression {
std::vector<TypeExpression*> args = {})
: IdentifierExpression(pos, {}, name, std::move(args)) {}
bool IsThis() const { return name->value == kThisParameterName; }
void VisitAllSubExpressions(VisitCallback callback) override {
callback(this);
}
std::vector<std::string> namespace_qualification;
Identifier* name;
std::vector<TypeExpression*> generic_arguments;
......@@ -240,6 +251,14 @@ struct IntrinsicCallExpression : Expression {
name(std::move(name)),
generic_arguments(std::move(generic_arguments)),
arguments(std::move(arguments)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
for (auto argument : arguments) {
argument->VisitAllSubExpressions(callback);
}
callback(this);
}
std::string name;
std::vector<TypeExpression*> generic_arguments;
std::vector<Expression*> arguments;
......@@ -256,6 +275,16 @@ struct CallMethodExpression : Expression {
method(method),
arguments(std::move(arguments)),
labels(std::move(labels)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
target->VisitAllSubExpressions(callback);
method->VisitAllSubExpressions(callback);
for (auto argument : arguments) {
argument->VisitAllSubExpressions(callback);
}
callback(this);
}
Expression* target;
IdentifierExpression* method;
std::vector<Expression*> arguments;
......@@ -271,6 +300,15 @@ struct CallExpression : Expression {
callee(callee),
arguments(std::move(arguments)),
labels(std::move(labels)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
callee->VisitAllSubExpressions(callback);
for (auto argument : arguments) {
argument->VisitAllSubExpressions(callback);
}
callback(this);
}
IdentifierExpression* callee;
std::vector<Expression*> arguments;
std::vector<Identifier*> labels;
......@@ -288,6 +326,14 @@ struct StructExpression : Expression {
: Expression(kKind, pos),
type(type),
initializers(std::move(initializers)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
for (auto& initializer : initializers) {
initializer.expression->VisitAllSubExpressions(callback);
}
callback(this);
}
TypeExpression* type;
std::vector<NameAndExpression> initializers;
};
......@@ -296,6 +342,13 @@ struct LogicalOrExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalOrExpression)
LogicalOrExpression(SourcePosition pos, Expression* left, Expression* right)
: Expression(kKind, pos), left(left), right(right) {}
void VisitAllSubExpressions(VisitCallback callback) override {
left->VisitAllSubExpressions(callback);
right->VisitAllSubExpressions(callback);
callback(this);
}
Expression* left;
Expression* right;
};
......@@ -304,6 +357,13 @@ struct LogicalAndExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalAndExpression)
LogicalAndExpression(SourcePosition pos, Expression* left, Expression* right)
: Expression(kKind, pos), left(left), right(right) {}
void VisitAllSubExpressions(VisitCallback callback) override {
left->VisitAllSubExpressions(callback);
right->VisitAllSubExpressions(callback);
callback(this);
}
Expression* left;
Expression* right;
};
......@@ -312,6 +372,12 @@ struct SpreadExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(SpreadExpression)
SpreadExpression(SourcePosition pos, Expression* spreadee)
: Expression(kKind, pos), spreadee(spreadee) {}
void VisitAllSubExpressions(VisitCallback callback) override {
spreadee->VisitAllSubExpressions(callback);
callback(this);
}
Expression* spreadee;
};
......@@ -323,6 +389,14 @@ struct ConditionalExpression : Expression {
condition(condition),
if_true(if_true),
if_false(if_false) {}
void VisitAllSubExpressions(VisitCallback callback) override {
condition->VisitAllSubExpressions(callback);
if_true->VisitAllSubExpressions(callback);
if_false->VisitAllSubExpressions(callback);
callback(this);
}
Expression* condition;
Expression* if_true;
Expression* if_false;
......@@ -332,6 +406,11 @@ struct StringLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StringLiteralExpression)
StringLiteralExpression(SourcePosition pos, std::string literal)
: Expression(kKind, pos), literal(std::move(literal)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
callback(this);
}
std::string literal;
};
......@@ -339,6 +418,11 @@ struct NumberLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(NumberLiteralExpression)
NumberLiteralExpression(SourcePosition pos, std::string name)
: Expression(kKind, pos), number(std::move(name)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
callback(this);
}
std::string number;
};
......@@ -347,6 +431,13 @@ struct ElementAccessExpression : LocationExpression {
ElementAccessExpression(SourcePosition pos, Expression* array,
Expression* index)
: LocationExpression(kKind, pos), array(array), index(index) {}
void VisitAllSubExpressions(VisitCallback callback) override {
array->VisitAllSubExpressions(callback);
index->VisitAllSubExpressions(callback);
callback(this);
}
Expression* array;
Expression* index;
};
......@@ -356,6 +447,12 @@ struct FieldAccessExpression : LocationExpression {
FieldAccessExpression(SourcePosition pos, Expression* object,
Identifier* field)
: LocationExpression(kKind, pos), object(object), field(field) {}
void VisitAllSubExpressions(VisitCallback callback) override {
object->VisitAllSubExpressions(callback);
callback(this);
}
Expression* object;
Identifier* field;
};
......@@ -364,6 +461,12 @@ struct DereferenceExpression : LocationExpression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(DereferenceExpression)
DereferenceExpression(SourcePosition pos, Expression* reference)
: LocationExpression(kKind, pos), reference(reference) {}
void VisitAllSubExpressions(VisitCallback callback) override {
reference->VisitAllSubExpressions(callback);
callback(this);
}
Expression* reference;
};
......@@ -378,6 +481,13 @@ struct AssignmentExpression : Expression {
location(location),
op(std::move(op)),
value(value) {}
void VisitAllSubExpressions(VisitCallback callback) override {
location->VisitAllSubExpressions(callback);
value->VisitAllSubExpressions(callback);
callback(this);
}
Expression* location;
base::Optional<std::string> op;
Expression* value;
......@@ -390,6 +500,12 @@ struct IncrementDecrementExpression : Expression {
IncrementDecrementExpression(SourcePosition pos, Expression* location,
IncrementDecrementOperator op, bool postfix)
: Expression(kKind, pos), location(location), op(op), postfix(postfix) {}
void VisitAllSubExpressions(VisitCallback callback) override {
location->VisitAllSubExpressions(callback);
callback(this);
}
Expression* location;
IncrementDecrementOperator op;
bool postfix;
......@@ -407,6 +523,12 @@ struct AssumeTypeImpossibleExpression : Expression {
: Expression(kKind, pos),
excluded_type(excluded_type),
expression(expression) {}
void VisitAllSubExpressions(VisitCallback callback) override {
expression->VisitAllSubExpressions(callback);
callback(this);
}
TypeExpression* excluded_type;
Expression* expression;
};
......@@ -418,6 +540,14 @@ struct NewExpression : Expression {
: Expression(kKind, pos),
type(type),
initializers(std::move(initializers)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
for (auto& initializer : initializers) {
initializer.expression->VisitAllSubExpressions(callback);
}
callback(this);
}
TypeExpression* type;
std::vector<NameAndExpression> initializers;
};
......
......@@ -524,9 +524,9 @@ std::string CSAGenerator::PreCallableExceptionPreparation(
if (catch_block) {
catch_name = FreshCatchName();
out_ << " compiler::CodeAssemblerExceptionHandlerLabel " << catch_name
<< "_label(&ca_, compiler::CodeAssemblerLabel::kDeferred);\n";
<< "__label(&ca_, compiler::CodeAssemblerLabel::kDeferred);\n";
out_ << " { compiler::CodeAssemblerScopedExceptionHandler s(&ca_, &"
<< catch_name << "_label);\n";
<< catch_name << "__label);\n";
}
return catch_name;
}
......@@ -537,7 +537,7 @@ void CSAGenerator::PostCallableExceptionPreparation(
if (catch_block) {
std::string block_name = BlockName(*catch_block);
out_ << " }\n";
out_ << " if (" << catch_name << "_label.is_used()) {\n";
out_ << " if (" << catch_name << "__label.is_used()) {\n";
out_ << " compiler::CodeAssemblerLabel " << catch_name
<< "_skip(&ca_);\n";
if (!return_type->IsNever()) {
......@@ -545,7 +545,7 @@ void CSAGenerator::PostCallableExceptionPreparation(
}
out_ << " compiler::TNode<Object> " << catch_name
<< "_exception_object;\n";
out_ << " ca_.Bind(&" << catch_name << "_label, &" << catch_name
out_ << " ca_.Bind(&" << catch_name << "__label, &" << catch_name
<< "_exception_object);\n";
out_ << " ca_.Goto(&" << block_name;
for (size_t i = 0; i < stack->Size(); ++i) {
......
......@@ -15,8 +15,13 @@ namespace internal {
namespace torque {
static constexpr const char* const kFromConstexprMacroName = "FromConstexpr";
static constexpr const char* kTrueLabelName = "_True";
static constexpr const char* kFalseLabelName = "_False";
static constexpr const char* kTrueLabelName = "__True";
static constexpr const char* kFalseLabelName = "__False";
static constexpr const char* kMacroEndLabelName = "__macro_end";
static constexpr const char* kBreakLabelName = "__break";
static constexpr const char* kContinueLabelName = "__continue";
static constexpr const char* kCatchLabelName = "__catch";
static constexpr const char* kNextCaseLabelName = "__NextCase";
template <class T>
std::vector<T*> FilterDeclarables(const std::vector<Declarable*> list) {
......
......@@ -180,14 +180,15 @@ VisitResult ImplementationVisitor::InlineMacro(
DCHECK(macro->IsMethod());
LocalValue this_value = LocalValue{!this_reference->IsVariableAccess(),
this_reference->GetVisitResult()};
parameter_bindings.Add(kThisParameterName, this_value);
parameter_bindings.Add(kThisParameterName, this_value, true);
}
size_t i = 0;
for (auto arg : arguments) {
if (this_reference && i == signature.implicit_count) i++;
const bool mark_as_used = signature.implicit_count > i;
const Identifier* name = macro->parameter_names()[i++];
parameter_bindings.Add(name, LocalValue{true, arg});
parameter_bindings.Add(name, LocalValue{true, arg}, mark_as_used);
}
DCHECK_EQ(label_blocks.size(), signature.labels.size());
......@@ -218,7 +219,7 @@ VisitResult ImplementationVisitor::InlineMacro(
}
}
macro_end = assembler().NewBlock(std::move(stack));
macro_end_binding.emplace(&LabelBindingsManager::Get(), "_macro_end",
macro_end_binding.emplace(&LabelBindingsManager::Get(), kMacroEndLabelName,
LocalLabel{macro_end, {return_type}});
} else {
SetReturnValue(VisitResult::NeverResult());
......@@ -381,13 +382,15 @@ namespace {
std::string AddParameter(size_t i, Builtin* builtin,
Stack<std::string>* parameters,
Stack<const Type*>* parameter_types,
BlockBindings<LocalValue>* parameter_bindings) {
BlockBindings<LocalValue>* parameter_bindings,
bool mark_as_used) {
const Identifier* name = builtin->signature().parameter_names[i];
const Type* type = builtin->signature().types()[i];
std::string external_name = "parameter" + std::to_string(i);
parameters->Push(external_name);
StackRange range = parameter_types->PushMany(LowerType(type));
parameter_bindings->Add(name, LocalValue{true, VisitResult(type, range)});
parameter_bindings->Add(name, LocalValue{true, VisitResult(type, range)},
mark_as_used);
return external_name;
}
......@@ -413,8 +416,10 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
BlockBindings<LocalValue> parameter_bindings(&ValueBindingsManager::Get());
// Context
std::string parameter0 = AddParameter(0, builtin, &parameters,
&parameter_types, &parameter_bindings);
const bool context_is_implicit = signature.implicit_count > 0;
std::string parameter0 =
AddParameter(0, builtin, &parameters, &parameter_types,
&parameter_bindings, context_is_implicit);
source_out() << " TNode<Context> " << parameter0
<< " = UncheckedCast<Context>(Parameter("
<< "Descriptor::kContext));\n";
......@@ -426,7 +431,7 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
source_out()
<< " Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);\n";
std::string parameter1 = AddParameter(
1, builtin, &parameters, &parameter_types, &parameter_bindings);
1, builtin, &parameters, &parameter_types, &parameter_bindings, true);
source_out()
<< " TNode<IntPtrT> arguments_length(ChangeInt32ToIntPtr(argc));\n";
source_out() << " TNode<RawPtrT> arguments_frame = "
......@@ -444,9 +449,9 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
parameters.Push("torque_arguments.length");
const Type* arguments_type = TypeOracle::GetArgumentsType();
StackRange range = parameter_types.PushMany(LowerType(arguments_type));
parameter_bindings.Add(
*signature.arguments_variable,
LocalValue{true, VisitResult(arguments_type, range)});
parameter_bindings.Add(*signature.arguments_variable,
LocalValue{true, VisitResult(arguments_type, range)},
true);
first = 2;
}
......@@ -455,8 +460,9 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
if (i < first) continue;
const std::string& parameter_name = signature.parameter_names[i]->value;
const Type* type = signature.types()[i];
const bool mark_as_used = signature.implicit_count > i;
std::string var = AddParameter(i, builtin, &parameters, &parameter_types,
&parameter_bindings);
&parameter_bindings, mark_as_used);
source_out() << " " << type->GetGeneratedTypeName() << " " << var << " = "
<< "UncheckedCast<" << type->GetGeneratedTNodeTypeName()
<< ">(Parameter(Descriptor::k"
......@@ -962,6 +968,23 @@ const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
"Torque assert '" + FormatAssertSource(stmt->source) + "' failed"});
assembler().Bind(true_block);
} else {
// Visit the expression so bindings only used in asserts are marked
// as such. Otherwise they might be wrongly reported as unused bindings
// in release builds.
stmt->expression->VisitAllSubExpressions([](Expression* expression) {
if (auto id = IdentifierExpression::DynamicCast(expression)) {
ValueBindingsManager::Get().TryLookup(id->name->value);
} else if (auto call = CallExpression::DynamicCast(expression)) {
for (Identifier* label : call->labels) {
LabelBindingsManager::Get().TryLookup(label->value);
}
} else if (auto call = CallMethodExpression::DynamicCast(expression)) {
for (Identifier* label : call->labels) {
LabelBindingsManager::Get().TryLookup(label->value);
}
}
});
}
return TypeOracle::GetVoidType();
}
......@@ -979,7 +1002,7 @@ const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
ReportError(s.str());
}
LocalLabel* end =
current_callable->IsMacro() ? LookupLabel("_macro_end") : nullptr;
current_callable->IsMacro() ? LookupLabel(kMacroEndLabelName) : nullptr;
if (current_callable->HasReturnValue()) {
if (!stmt->value) {
std::stringstream s;
......@@ -1316,7 +1339,8 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
}
const Type* ImplementationVisitor::Visit(BreakStatement* stmt) {
base::Optional<Binding<LocalLabel>*> break_label = TryLookupLabel("_break");
base::Optional<Binding<LocalLabel>*> break_label =
TryLookupLabel(kBreakLabelName);
if (!break_label) {
ReportError("break used outside of loop");
}
......@@ -1326,7 +1350,7 @@ const Type* ImplementationVisitor::Visit(BreakStatement* stmt) {
const Type* ImplementationVisitor::Visit(ContinueStatement* stmt) {
base::Optional<Binding<LocalLabel>*> continue_label =
TryLookupLabel("_continue");
TryLookupLabel(kContinueLabelName);
if (!continue_label) {
ReportError("continue used outside of loop");
}
......@@ -2487,7 +2511,7 @@ bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
base::Optional<Block*> ImplementationVisitor::GetCatchBlock() {
base::Optional<Block*> catch_block;
if (base::Optional<Binding<LocalLabel>*> catch_handler =
TryLookupLabel("_catch")) {
TryLookupLabel(kCatchLabelName)) {
catch_block = assembler().NewBlock(base::nullopt, true);
}
return catch_block;
......@@ -2497,7 +2521,7 @@ void ImplementationVisitor::GenerateCatchBlock(
base::Optional<Block*> catch_block) {
if (catch_block) {
base::Optional<Binding<LocalLabel>*> catch_handler =
TryLookupLabel("_catch");
TryLookupLabel(kCatchLabelName);
if (assembler().CurrentBlockIsComplete()) {
assembler().Bind(*catch_block);
assembler().Goto((*catch_handler)->block, 1);
......@@ -3279,7 +3303,7 @@ void GenerateClassFieldVerifier(const std::string& class_name,
f.is_weak ? "VerifyMaybeObjectPointer" : "VerifyPointer";
const char* index_offset = f.index ? " + i * kTaggedSize" : "";
// Name the local var based on the field name for nicer CHECK output.
const std::string value = f.name_and_type.name + "_value";
const std::string value = f.name_and_type.name + "__value";
// Read the field.
cc_contents << " " << object_type << " " << value << " = " << read_fn
......
......@@ -171,7 +171,15 @@ template <class T>
class BindingsManager {
public:
base::Optional<Binding<T>*> TryLookup(const std::string& name) {
return current_bindings_[name];
if (name.length() >= 2 && name[0] == '_' && name[1] != '_') {
Error("Trying to reference '", name, "' which is marked as unused.")
.Throw();
}
auto binding = current_bindings_[name];
if (binding) {
(*binding)->SetUsed();
}
return binding;
}
private:
......@@ -188,7 +196,8 @@ class Binding : public T {
: T(std::forward<Args>(args)...),
manager_(manager),
name_(name),
previous_binding_(this) {
previous_binding_(this),
used_(false) {
std::swap(previous_binding_, manager_->current_bindings_[name]);
}
template <class... Args>
......@@ -196,16 +205,29 @@ class Binding : public T {
: Binding(manager, name->value, std::forward<Args>(args)...) {
declaration_position_ = name->pos;
}
~Binding() { manager_->current_bindings_[name_] = previous_binding_; }
~Binding() {
manager_->current_bindings_[name_] = previous_binding_;
if (!used_ && name_.length() > 0 && name_[0] != '_') {
Lint(BindingTypeString(), "'", name_,
"' is never used. Prefix with '_' if this is intentional.")
.Position(declaration_position_);
}
}
std::string BindingTypeString() const { return ""; }
const std::string& name() const { return name_; }
SourcePosition declaration_position() const { return declaration_position_; }
bool Used() const { return used_; }
void SetUsed() { used_ = true; }
private:
BindingsManager<T>* manager_;
const std::string name_;
base::Optional<Binding*> previous_binding_;
SourcePosition declaration_position_ = CurrentSourcePosition::Get();
bool used_;
DISALLOW_COPY_AND_ASSIGN(Binding);
};
......@@ -213,16 +235,20 @@ template <class T>
class BlockBindings {
public:
explicit BlockBindings(BindingsManager<T>* manager) : manager_(manager) {}
void Add(std::string name, T value) {
void Add(std::string name, T value, bool mark_as_used = false) {
ReportErrorIfAlreadyBound(name);
bindings_.push_back(base::make_unique<Binding<T>>(manager_, std::move(name),
std::move(value)));
auto binding =
base::make_unique<Binding<T>>(manager_, name, std::move(value));
if (mark_as_used) binding->SetUsed();
bindings_.push_back(std::move(binding));
}
void Add(const Identifier* name, T value) {
void Add(const Identifier* name, T value, bool mark_as_used = false) {
ReportErrorIfAlreadyBound(name->value);
bindings_.push_back(
base::make_unique<Binding<T>>(manager_, name, std::move(value)));
auto binding =
base::make_unique<Binding<T>>(manager_, name, std::move(value));
if (mark_as_used) binding->SetUsed();
bindings_.push_back(std::move(binding));
}
std::vector<Binding<T>*> bindings() const {
......@@ -264,6 +290,15 @@ struct LocalLabel {
: block(block), parameter_types(std::move(parameter_types)) {}
};
template <>
inline std::string Binding<LocalValue>::BindingTypeString() const {
return "Variable ";
}
template <>
inline std::string Binding<LocalLabel>::BindingTypeString() const {
return "Label ";
}
struct Arguments {
VisitResultVector parameters;
std::vector<Binding<LocalLabel>*> labels;
......@@ -464,9 +499,9 @@ class ImplementationVisitor {
class BreakContinueActivator {
public:
BreakContinueActivator(Block* break_block, Block* continue_block)
: break_binding_{&LabelBindingsManager::Get(), "_break",
: break_binding_{&LabelBindingsManager::Get(), kBreakLabelName,
LocalLabel{break_block}},
continue_binding_{&LabelBindingsManager::Get(), "_continue",
continue_binding_{&LabelBindingsManager::Get(), kContinueLabelName,
LocalLabel{continue_block}} {}
private:
......
......@@ -9,6 +9,7 @@
#include "src/common/globals.h"
#include "src/torque/constants.h"
#include "src/torque/declarations.h"
#include "src/torque/earley-parser.h"
#include "src/torque/torque-parser.h"
#include "src/torque/utils.h"
......@@ -281,7 +282,7 @@ Expression* MakeCall(IdentifierExpression* callee,
continue;
}
}
auto label_name = std::string("_label") + std::to_string(label_id++);
auto label_name = std::string("__label") + std::to_string(label_id++);
auto label_id = MakeNode<Identifier>(label_name);
label_id->pos = SourcePosition::Invalid();
labels.push_back(label_id);
......@@ -923,14 +924,14 @@ base::Optional<ParseResult> MakeTypeswitchStatement(
{
CurrentSourcePosition::Scope current_source_position(expression->pos);
current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
true, MakeNode<Identifier>("_value"), base::nullopt, expression));
true, MakeNode<Identifier>("__value"), base::nullopt, expression));
}
TypeExpression* accumulated_types;
for (size_t i = 0; i < cases.size(); ++i) {
CurrentSourcePosition::Scope current_source_position(cases[i].pos);
Expression* value =
MakeNode<IdentifierExpression>(MakeNode<Identifier>("_value"));
MakeNode<IdentifierExpression>(MakeNode<Identifier>("__value"));
if (i >= 1) {
value =
MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
......@@ -942,12 +943,12 @@ base::Optional<ParseResult> MakeTypeswitchStatement(
std::vector<Expression*>{value},
std::vector<Statement*>{MakeNode<ExpressionStatement>(
MakeNode<IdentifierExpression>(
MakeNode<Identifier>("_NextCase")))});
MakeNode<Identifier>(kNextCaseLabelName)))});
case_block = MakeNode<BlockStatement>();
} else {
case_block = current_block;
}
std::string name = "_case_value";
std::string name = "__case_value";
if (cases[i].name) name = *cases[i].name;
case_block->statements.push_back(MakeNode<VarDeclarationStatement>(
true, MakeNode<Identifier>(name), cases[i].type, value));
......@@ -957,7 +958,7 @@ base::Optional<ParseResult> MakeTypeswitchStatement(
current_block->statements.push_back(
MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
false, MakeNode<StatementExpression>(case_block),
MakeNode<LabelBlock>(MakeNode<Identifier>("_NextCase"),
MakeNode<LabelBlock>(MakeNode<Identifier>(kNextCaseLabelName),
ParameterList::Empty(), next_block))));
current_block = next_block;
}
......@@ -1107,8 +1108,8 @@ base::Optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
parameters.types.push_back(
MakeNode<BasicTypeExpression>(std::vector<std::string>{}, "Object"));
parameters.has_varargs = false;
LabelBlock* result = MakeNode<LabelBlock>(MakeNode<Identifier>("_catch"),
std::move(parameters), body);
LabelBlock* result = MakeNode<LabelBlock>(
MakeNode<Identifier>(kCatchLabelName), std::move(parameters), body);
return ParseResult{result};
}
......@@ -1339,9 +1340,12 @@ struct TorqueGrammar : Grammar {
}
static bool MatchIdentifier(InputPosition* pos) {
if (!MatchChar(std::isalpha, pos)) return false;
while (MatchChar(std::isalnum, pos) || MatchString("_", pos)) {
InputPosition current = *pos;
MatchString("_", &current);
if (!MatchChar(std::isalpha, &current)) return false;
while (MatchChar(std::isalnum, &current) || MatchString("_", &current)) {
}
*pos = current;
return true;
}
......
......@@ -180,12 +180,16 @@ bool IsMachineType(const std::string& s) {
bool IsLowerCamelCase(const std::string& s) {
if (s.empty()) return false;
return islower(s[0]) && !ContainsUnderscore(s);
size_t start = 0;
if (s[0] == '_') start = 1;
return islower(s[start]) && !ContainsUnderscore(s.substr(start));
}
bool IsUpperCamelCase(const std::string& s) {
if (s.empty()) return false;
return isupper(s[0]) && !ContainsUnderscore(s);
size_t start = 0;
if (s[0] == '_') start = 1;
return isupper(s[start]) && !ContainsUnderscore(s.substr(1));
}
bool IsSnakeCase(const std::string& s) {
......
......@@ -87,11 +87,11 @@ namespace test {
}
}
builtin GenericBuiltinTest<T: type>(c: Context, param: T): Object {
builtin GenericBuiltinTest<T: type>(_c: Context, _param: T): Object {
return Null;
}
GenericBuiltinTest<Object>(c: Context, param: Object): Object {
GenericBuiltinTest<Object>(_c: Context, param: Object): Object {
return param;
}
......@@ -136,7 +136,7 @@ namespace test {
}
}
macro GenericMacroTest<T: type>(param: T): Object {
macro GenericMacroTest<T: type>(_param: T): Object {
return Undefined;
}
......@@ -144,8 +144,8 @@ namespace test {
return param2;
}
macro GenericMacroTestWithLabels<T: type>(param: T): Object
labels X {
macro GenericMacroTestWithLabels<T: type>(_param: T): Object
labels _X {
return Undefined;
}
......@@ -157,7 +157,7 @@ namespace test {
@export
macro TestMacroSpecialization() {
try {
const smi0: Smi = 0;
const _smi0: Smi = 0;
check(GenericMacroTest<Smi>(0) == Undefined);
check(GenericMacroTest<Smi>(1) == Undefined);
check(GenericMacroTest<Object>(Null) == Null);
......@@ -175,10 +175,10 @@ namespace test {
}
}
builtin TestHelperPlus1(context: Context, x: Smi): Smi {
builtin TestHelperPlus1(_context: Context, x: Smi): Smi {
return x + 1;
}
builtin TestHelperPlus2(context: Context, x: Smi): Smi {
builtin TestHelperPlus2(_context: Context, x: Smi): Smi {
return x + 2;
}
......@@ -193,8 +193,8 @@ namespace test {
@export
macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
let var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
let var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
return True;
}
......@@ -240,8 +240,8 @@ namespace test {
@export
macro TestLargeIntegerLiterals(implicit c: Context)() {
let x: int32 = 0x40000000;
let y: int32 = 0x7fffffff;
let _x: int32 = 0x40000000;
let _y: int32 = 0x7fffffff;
}
@export
......@@ -312,14 +312,14 @@ namespace test {
macro TestStruct3(implicit context: Context)(): TestStructA {
let a: TestStructA =
TestStructA{indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), i: 13, k: 5};
let b: TestStructA = a;
let _b: TestStructA = a;
let c: TestStructA = TestStruct2();
a.i = TestStruct1(c);
a.k = a.i;
let d: TestStructB;
d.x = a;
d = TestStructB{x: a, y: 7};
let e: TestStructA = d.x;
let _e: TestStructA = d.x;
let f: Smi = TestStructA{
indexes: UnsafeCast<FixedArray>(kEmptyFixedArray),
i: 27,
......@@ -347,7 +347,7 @@ namespace test {
try {
TestStructInLabel() otherwise Foo;
}
label Foo(s: TestStructA) {}
label Foo(_s: TestStructA) {}
}
// This macro tests different versions of the for-loop where some parts
......@@ -447,14 +447,14 @@ namespace test {
}
// Test if we can handle uninitialized values on the stack.
let i: Smi;
let _i: Smi;
for (let j: Smi = 0; j < 10; ++j) {
}
}
@export
macro TestSubtyping(x: Smi) {
const foo: Object = x;
const _foo: Object = x;
}
macro IncrementIfSmi<A: type>(x: A): A {
......@@ -473,7 +473,7 @@ namespace test {
int32 {
let result: int32 = 0;
typeswitch (IncrementIfSmi(x)) {
case (x: FixedArray): {
case (_x: FixedArray): {
result = result + 1;
}
case (Number): {
......@@ -490,7 +490,7 @@ namespace test {
case (a: FixedArray): {
result = result + Convert<int32>(a.length);
}
case (x: HeapNumber): {
case (_x: HeapNumber): {
result = result + 7;
}
}
......@@ -509,13 +509,13 @@ namespace test {
@export
macro TestTypeswitchAsanLsanFailure(implicit context: Context)(obj: Object) {
typeswitch (obj) {
case (o: Smi): {
case (_o: Smi): {
}
case (o: JSTypedArray): {
case (_o: JSTypedArray): {
}
case (o: JSReceiver): {
case (_o: JSReceiver): {
}
case (o: HeapObject): {
case (_o: HeapObject): {
}
}
}
......@@ -698,7 +698,7 @@ namespace test {
let r: Smi = 0;
try {
ThrowTypeError(kInvalidArrayLength);
} catch (e) {
} catch (_e) {
r = 1;
return r;
}
......@@ -714,7 +714,7 @@ namespace test {
let r: Smi = 0;
try {
TestCatch2Wrapper();
} catch (e) {
} catch (_e) {
r = 2;
return r;
}
......@@ -722,7 +722,7 @@ namespace test {
@export
macro TestCatch3WrapperWithLabel(implicit context: Context)():
never labels Abort {
never labels _Abort {
ThrowTypeError(kInvalidArrayLength);
}
......@@ -735,7 +735,7 @@ namespace test {
label Abort {
return -1;
}
catch (e) {
catch (_e) {
r = 2;
return r;
}
......@@ -751,13 +751,13 @@ namespace test {
const t1: Object = iterator::GetIteratorMethod(o);
const t2: iterator::IteratorRecord = iterator::GetIterator(o);
const t3: Object = iterator::IteratorStep(t2) otherwise Fail;
const _t3: Object = iterator::IteratorStep(t2) otherwise Fail;
const t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
const t5: Object = iterator::IteratorValue(t4);
const t6: Object = iterator::IteratorValue(t4, map);
const _t6: Object = iterator::IteratorValue(t4, map);
const t7: JSArray = iterator::IterableToList(t1, t1);
const _t7: JSArray = iterator::IterableToList(t1, t1);
iterator::IteratorCloseOnException(t2, t5);
}
......@@ -772,13 +772,13 @@ namespace test {
assert(frameType == STUB_FRAME);
assert(f.caller == LoadParentFramePointer());
typeswitch (f) {
case (f: StandardFrame): {
case (_f: StandardFrame): {
unreachable;
}
case (f: ArgumentsAdaptorFrame): {
case (_f: ArgumentsAdaptorFrame): {
unreachable;
}
case (f: StubFrame): {
case (_f: StubFrame): {
}
}
}
......@@ -860,7 +860,7 @@ namespace test {
const x = StructWithConst{a: Null, b: 1};
let y = StructWithConst{a: Null, b: 1};
y.a = Undefined;
const copy = x;
const _copy = x;
}
struct TestIterator {
......
......@@ -213,6 +213,82 @@ TEST(Torque, ConstexprLetBindingDoesNotCrash) {
HasSubstr("Use 'const' instead of 'let' for variable 'foo'"));
}
TEST(Torque, DoubleUnderScorePrefixIllegalForIdentifiers) {
ExpectFailingCompilation(R"(
macro Foo() {
let __x;
}
)",
HasSubstr("Lexer Error"));
}
TEST(Torque, UnusedLetBindingLintError) {
ExpectFailingCompilation(R"(
macro Foo(y: Smi) {
let x: Smi = y;
}
)",
HasSubstr("Variable 'x' is never used."));
}
TEST(Torque, UnderscorePrefixSilencesUnusedWarning) {
ExpectSuccessfulCompilation(R"(
macro Foo(y: Smi) {
let _x: Smi = y;
}
)");
}
TEST(Torque, UsingUnderscorePrefixedIdentifierError) {
ExpectFailingCompilation(R"(
macro Foo(y: Smi) {
let _x: Smi = y;
check(_x == y);
}
)",
HasSubstr("Trying to reference '_x'"));
}
TEST(Torque, UnusedArgumentLintError) {
ExpectFailingCompilation(R"(
macro Foo(x: Smi) {}
)",
HasSubstr("Variable 'x' is never used."));
}
TEST(Torque, UsingUnderscorePrefixedArgumentSilencesWarning) {
ExpectSuccessfulCompilation(R"(
macro Foo(_y: Smi) {}
)");
}
TEST(Torque, UnusedLabelLintError) {
ExpectFailingCompilation(R"(
macro Foo() labels Bar {}
)",
HasSubstr("Label 'Bar' is never used."));
}
TEST(Torque, UsingUnderScorePrefixLabelSilencesWarning) {
ExpectSuccessfulCompilation(R"(
macro Foo() labels _Bar {}
)");
}
TEST(Torque, NoUnusedWarningForImplicitArguments) {
ExpectSuccessfulCompilation(R"(
macro Foo(implicit c: Context, r: JSReceiver)() {}
)");
}
TEST(Torque, NoUnusedWarningForVariablesOnlyUsedInAsserts) {
ExpectSuccessfulCompilation(R"(
macro Foo(x: bool) {
assert(x);
}
)");
}
} // namespace torque
} // namespace internal
} // namespace v8
......@@ -389,8 +389,8 @@ namespace array {
}
CanUseSameAccessor<GenericElementsAccessor>(
context: Context, receiver: JSReceiver, initialReceiverMap: Object,
initialReceiverLength: Number): Boolean {
_context: Context, _receiver: JSReceiver, _initialReceiverMap: Object,
_initialReceiverLength: Number): Boolean {
// Do nothing. We are already on the slow path.
return True;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment