Commit 1d08ecaf authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[torque] Simplify and cleanup Cast and UnsafeCast

Change-Id: I57e21c5bc754ca07f52032f85ec8aeff96448dd0
Reviewed-on: https://chromium-review.googlesource.com/c/1342929
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57855}
parent 524ab4e1
...@@ -115,7 +115,7 @@ namespace array { ...@@ -115,7 +115,7 @@ namespace array {
const a: JSArray = Cast<JSArray>(o) otherwise Slow; const a: JSArray = Cast<JSArray>(o) otherwise Slow;
const map: Map = a.map; const map: Map = a.map;
if (!IsPrototypeInitialArrayPrototype(context, map)) goto Slow; if (!IsPrototypeInitialArrayPrototype(map)) goto Slow;
const elementsKind: ElementsKind = map.elements_kind; const elementsKind: ElementsKind = map.elements_kind;
if (!IsFastElementsKind(elementsKind)) goto Slow; if (!IsFastElementsKind(elementsKind)) goto Slow;
......
...@@ -323,7 +323,7 @@ namespace array { ...@@ -323,7 +323,7 @@ namespace array {
try { try {
const array: JSArray = Cast<JSArray>(receiver) otherwise IfSlowPath; const array: JSArray = Cast<JSArray>(receiver) otherwise IfSlowPath;
if (array.length != lenNumber) goto IfSlowPath; if (array.length != lenNumber) goto IfSlowPath;
if (!IsPrototypeInitialArrayPrototype(context, map)) goto IfSlowPath; if (!IsPrototypeInitialArrayPrototype(map)) goto IfSlowPath;
if (IsNoElementsProtectorCellInvalid()) goto IfSlowPath; if (IsNoElementsProtectorCellInvalid()) goto IfSlowPath;
if (IsElementsKindLessThanOrEqual(kind, HOLEY_ELEMENTS)) { if (IsElementsKindLessThanOrEqual(kind, HOLEY_ELEMENTS)) {
......
...@@ -7,7 +7,8 @@ namespace array { ...@@ -7,7 +7,8 @@ namespace array {
elements: FixedArrayBase, index: Smi): Object elements: FixedArrayBase, index: Smi): Object
labels IfHole; labels IfHole;
LoadWithHoleCheck<FixedArray>(elements: FixedArrayBase, index: Smi): Object LoadWithHoleCheck<FixedArray>(implicit context: Context)(
elements: FixedArrayBase, index: Smi): Object
labels IfHole { labels IfHole {
const elements: FixedArray = UnsafeCast<FixedArray>(elements); const elements: FixedArray = UnsafeCast<FixedArray>(elements);
const element: Object = elements[index]; const element: Object = elements[index];
...@@ -15,8 +16,8 @@ namespace array { ...@@ -15,8 +16,8 @@ namespace array {
return element; return element;
} }
LoadWithHoleCheck<FixedDoubleArray>(elements: FixedArrayBase, index: Smi): LoadWithHoleCheck<FixedDoubleArray>(implicit context: Context)(
Object elements: FixedArrayBase, index: Smi): Object
labels IfHole { labels IfHole {
const elements: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); const elements: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements);
const element: float64 = LoadDoubleWithHoleCheck(elements, index) const element: float64 = LoadDoubleWithHoleCheck(elements, index)
...@@ -44,7 +45,7 @@ namespace array { ...@@ -44,7 +45,7 @@ namespace array {
const same: Boolean = StrictEqual(searchElement, element); const same: Boolean = StrictEqual(searchElement, element);
if (same == True) { if (same == True) {
assert(IsFastJSArray(array, context)); assert(Is<FastJSArray>(array));
return k; return k;
} }
} }
...@@ -53,7 +54,7 @@ namespace array { ...@@ -53,7 +54,7 @@ namespace array {
--k; --k;
} }
assert(IsFastJSArray(array, context)); assert(Is<FastJSArray>(array));
return -1; return -1;
} }
......
...@@ -6,19 +6,19 @@ namespace array { ...@@ -6,19 +6,19 @@ namespace array {
macro LoadElement<ElementsAccessor: type, T: type>( macro LoadElement<ElementsAccessor: type, T: type>(
elements: FixedArrayBase, index: Smi): T; elements: FixedArrayBase, index: Smi): T;
LoadElement<FastPackedSmiElements, Smi>(elements: FixedArrayBase, index: Smi): LoadElement<FastPackedSmiElements, Smi>(implicit context: Context)(
Smi { elements: FixedArrayBase, index: Smi): Smi {
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const elems: FixedArray = UnsafeCast<FixedArray>(elements);
return UnsafeCast<Smi>(elems[index]); return UnsafeCast<Smi>(elems[index]);
} }
LoadElement<FastPackedObjectElements, Object>( LoadElement<FastPackedObjectElements, Object>(implicit context: Context)(
elements: FixedArrayBase, index: Smi): Object { elements: FixedArrayBase, index: Smi): Object {
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const elems: FixedArray = UnsafeCast<FixedArray>(elements);
return elems[index]; return elems[index];
} }
LoadElement<FastPackedDoubleElements, float64>( LoadElement<FastPackedDoubleElements, float64>(implicit context: Context)(
elements: FixedArrayBase, index: Smi): float64 { elements: FixedArrayBase, index: Smi): float64 {
try { try {
const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements);
...@@ -32,21 +32,22 @@ namespace array { ...@@ -32,21 +32,22 @@ namespace array {
} }
macro StoreElement<ElementsAccessor: type, T: type>( macro StoreElement<ElementsAccessor: type, T: type>(
elements: FixedArrayBase, index: Smi, value: T); implicit context:
Context)(elements: FixedArrayBase, index: Smi, value: T);
StoreElement<FastPackedSmiElements, Smi>( StoreElement<FastPackedSmiElements, Smi>(implicit context: Context)(
elements: FixedArrayBase, index: Smi, value: Smi) { elements: FixedArrayBase, index: Smi, value: Smi) {
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const elems: FixedArray = UnsafeCast<FixedArray>(elements);
StoreFixedArrayElementSmi(elems, index, value, SKIP_WRITE_BARRIER); StoreFixedArrayElementSmi(elems, index, value, SKIP_WRITE_BARRIER);
} }
StoreElement<FastPackedObjectElements, Object>( StoreElement<FastPackedObjectElements, Object>(implicit context: Context)(
elements: FixedArrayBase, index: Smi, value: Object) { elements: FixedArrayBase, index: Smi, value: Object) {
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const elems: FixedArray = UnsafeCast<FixedArray>(elements);
elems[index] = value; elems[index] = value;
} }
StoreElement<FastPackedDoubleElements, float64>( StoreElement<FastPackedDoubleElements, float64>(implicit context: Context)(
elements: FixedArrayBase, index: Smi, value: float64) { elements: FixedArrayBase, index: Smi, value: float64) {
const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements);
StoreFixedDoubleArrayElementWithSmiIndex(elems, index, value); StoreFixedDoubleArrayElementWithSmiIndex(elems, index, value);
...@@ -56,7 +57,7 @@ namespace array { ...@@ -56,7 +57,7 @@ namespace array {
// whether a property is present, so we can simply swap them using fast // whether a property is present, so we can simply swap them using fast
// FixedArray loads/stores. // FixedArray loads/stores.
macro FastPackedArrayReverse<Accessor: type, T: type>( macro FastPackedArrayReverse<Accessor: type, T: type>(
elements: FixedArrayBase, length: Smi) { implicit context: Context)(elements: FixedArrayBase, length: Smi) {
let lower: Smi = 0; let lower: Smi = 0;
let upper: Smi = length - 1; let upper: Smi = length - 1;
......
...@@ -11,14 +11,14 @@ namespace array { ...@@ -11,14 +11,14 @@ namespace array {
elements: FixedArrayBase, first: Smi, count: Smi, elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedArrayType; capacity: Smi): FixedArrayType;
Extract<FixedArray>( Extract<FixedArray>(implicit context: Context)(
elements: FixedArrayBase, first: Smi, count: Smi, elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedArray { capacity: Smi): FixedArray {
return UnsafeCast<FixedArray>( return UnsafeCast<FixedArray>(
ExtractFixedArray(elements, first, count, capacity)); ExtractFixedArray(elements, first, count, capacity));
} }
Extract<FixedDoubleArray>( Extract<FixedDoubleArray>(implicit context: Context)(
elements: FixedArrayBase, first: Smi, count: Smi, elements: FixedArrayBase, first: Smi, count: Smi,
capacity: Smi): FixedDoubleArray { capacity: Smi): FixedDoubleArray {
if (elements == kEmptyFixedArray) { if (elements == kEmptyFixedArray) {
...@@ -51,7 +51,8 @@ namespace array { ...@@ -51,7 +51,8 @@ namespace array {
Convert<intptr>(srcIndex), Convert<intptr>(count)); Convert<intptr>(srcIndex), Convert<intptr>(count));
} }
macro FastSplice<FixedArrayType: type, ElementType: type>( macro FastSplice<FixedArrayType: type, ElementType: type>(implicit context:
Context)(
args: constexpr Arguments, a: JSArray, length: Smi, newLength: Smi, args: constexpr Arguments, a: JSArray, length: Smi, newLength: Smi,
lengthDelta: Smi, actualStart: Smi, insertCount: Smi, lengthDelta: Smi, actualStart: Smi, insertCount: Smi,
actualDeleteCount: Smi): void labels Bailout { actualDeleteCount: Smi): void labels Bailout {
...@@ -121,7 +122,7 @@ namespace array { ...@@ -121,7 +122,7 @@ namespace array {
const a: JSArray = Cast<JSArray>(o) otherwise Bailout; const a: JSArray = Cast<JSArray>(o) otherwise Bailout;
const map: Map = a.map; const map: Map = a.map;
if (!IsPrototypeInitialArrayPrototype(context, map)) goto Bailout; if (!IsPrototypeInitialArrayPrototype(map)) goto Bailout;
if (IsNoElementsProtectorCellInvalid()) goto Bailout; if (IsNoElementsProtectorCellInvalid()) goto Bailout;
if (IsArraySpeciesProtectorCellInvalid()) goto Bailout; if (IsArraySpeciesProtectorCellInvalid()) goto Bailout;
......
...@@ -14,7 +14,7 @@ namespace array { ...@@ -14,7 +14,7 @@ namespace array {
type FastDoubleElements; type FastDoubleElements;
type DictionaryElements; type DictionaryElements;
macro EnsureWriteableFastElements(array: JSArray) { macro EnsureWriteableFastElements(implicit context: Context)(array: JSArray) {
assert(IsFastElementsKind(array.map.elements_kind)); assert(IsFastElementsKind(array.map.elements_kind));
const elements: FixedArrayBase = array.elements; const elements: FixedArrayBase = array.elements;
...@@ -30,7 +30,7 @@ namespace array { ...@@ -30,7 +30,7 @@ namespace array {
assert(array.elements.map != kCOWMap); assert(array.elements.map != kCOWMap);
} }
macro IsJSArray(o: Object): bool { macro IsJSArray(implicit context: Context)(o: Object): bool {
try { try {
const array: JSArray = Cast<JSArray>(o) otherwise NotArray; const array: JSArray = Cast<JSArray>(o) otherwise NotArray;
return true; return true;
......
...@@ -522,59 +522,167 @@ extern macro TaggedToNumber(Object): Number ...@@ -522,59 +522,167 @@ extern macro TaggedToNumber(Object): Number
macro CastHeapObject<A: type>(o: HeapObject): A macro CastHeapObject<A: type>(o: HeapObject): A
labels CastError; labels CastError;
CastHeapObject<HeapObject>(o: HeapObject): HeapObject CastHeapObject<HeapObject>(o: HeapObject): HeapObject
labels CastError { labels CastError {
return o; return o;
} }
CastHeapObject<FixedArray>(o: HeapObject): FixedArray CastHeapObject<FixedArray>(o: HeapObject): FixedArray
labels CastError { labels CastError {
return HeapObjectToFixedArray(o) otherwise CastError; return HeapObjectToFixedArray(o) otherwise CastError;
} }
CastHeapObject<FixedDoubleArray>(o: HeapObject): FixedDoubleArray CastHeapObject<FixedDoubleArray>(o: HeapObject): FixedDoubleArray
labels CastError { labels CastError {
return HeapObjectToFixedDoubleArray(o) otherwise CastError; return HeapObjectToFixedDoubleArray(o) otherwise CastError;
} }
CastHeapObject<SloppyArgumentsElements>(o: HeapObject): SloppyArgumentsElements CastHeapObject<SloppyArgumentsElements>(o: HeapObject): SloppyArgumentsElements
labels CastError { labels CastError {
return HeapObjectToSloppyArgumentsElements(o) otherwise CastError; return HeapObjectToSloppyArgumentsElements(o) otherwise CastError;
} }
CastHeapObject<JSDataView>(o: HeapObject): JSDataView CastHeapObject<JSDataView>(o: HeapObject): JSDataView
labels CastError { labels CastError {
return HeapObjectToJSDataView(o) otherwise CastError; return HeapObjectToJSDataView(o) otherwise CastError;
} }
CastHeapObject<Callable>(o: HeapObject): Callable CastHeapObject<Callable>(o: HeapObject): Callable
labels CastError { labels CastError {
return HeapObjectToCallable(o) otherwise CastError; return HeapObjectToCallable(o) otherwise CastError;
} }
CastHeapObject<JSArray>(o: HeapObject): JSArray CastHeapObject<JSArray>(o: HeapObject): JSArray
labels CastError { labels CastError {
return HeapObjectToJSArray(o) otherwise CastError; return HeapObjectToJSArray(o) otherwise CastError;
} }
CastHeapObject<Context>(o: HeapObject): Context
labels CastError {
if (IsContext(o)) return %RawCast<Context>(o);
goto CastError;
}
CastHeapObject<JSObject>(o: HeapObject): JSObject
labels CastError {
if (IsJSObject(o)) return %RawCast<JSObject>(o);
goto CastError;
}
CastHeapObject<NumberDictionary>(o: HeapObject): NumberDictionary
labels CastError {
if (IsNumberDictionary(o)) return %RawCast<NumberDictionary>(o);
goto CastError;
}
CastHeapObject<FixedTypedArrayBase>(o: HeapObject): FixedTypedArrayBase
labels CastError {
if (IsFixedTypedArray(o)) return %RawCast<FixedTypedArrayBase>(o);
goto CastError;
}
CastHeapObject<String>(o: HeapObject): String CastHeapObject<String>(o: HeapObject): String
labels CastError { labels CastError {
return HeapObjectToString(o) otherwise CastError; return HeapObjectToString(o) otherwise CastError;
} }
CastHeapObject<Constructor>(o: HeapObject): Constructor CastHeapObject<Constructor>(o: HeapObject): Constructor
labels CastError { labels CastError {
return HeapObjectToConstructor(o) otherwise CastError; return HeapObjectToConstructor(o) otherwise CastError;
} }
macro Cast<A: type>(o: HeapObject): A CastHeapObject<HeapNumber>(o: HeapObject): HeapNumber
labels CastError {
if (IsHeapNumber(o)) return %RawCast<HeapNumber>(o);
goto CastError;
}
CastHeapObject<Map>(implicit context: Context)(o: HeapObject): Map
labels CastError {
if (IsMap(o)) return %RawCast<Map>(o);
goto CastError;
}
CastHeapObject<JSArgumentsObjectWithLength>(implicit context: Context)(
o: HeapObject): JSArgumentsObjectWithLength
labels CastError {
const map: Map = o.map;
try {
if (IsFastAliasedArgumentsMap(map)) goto True;
if (IsSloppyArgumentsMap(map)) goto True;
if (IsStrictArgumentsMap(map)) goto True;
if (IsSlowAliasedArgumentsMap(map)) goto True;
goto CastError;
}
label True {
return %RawCast<JSArgumentsObjectWithLength>(o);
}
}
CastHeapObject<FastJSArray>(implicit context: Context)(o: HeapObject):
FastJSArray
labels CastError {
const map: Map = o.map;
if (!IsJSArrayMap(map)) goto CastError;
// Bailout if receiver has slow elements.
const elementsKind: ElementsKind = LoadMapElementsKind(map);
if (!IsFastElementsKind(elementsKind)) goto CastError;
// Verify that our prototype is the initial array prototype.
if (!IsPrototypeInitialArrayPrototype(map)) goto CastError;
if (IsNoElementsProtectorCellInvalid()) goto CastError;
return %RawCast<FastJSArray>(o);
}
CastHeapObject<FastJSArrayForCopy>(implicit context: Context)(o: HeapObject):
FastJSArrayForCopy
labels CastError {
if (IsArraySpeciesProtectorCellInvalid()) goto CastError;
const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError;
return %RawCast<FastJSArrayForCopy>(o);
}
CastHeapObject<FastJSArrayWithNoCustomIteration>(implicit context: Context)(
o: HeapObject): FastJSArrayWithNoCustomIteration
labels CastError {
if (IsArrayIteratorProtectorCellInvalid()) goto CastError;
const a: FastJSArray = Cast<FastJSArray>(o) otherwise CastError;
return %RawCast<FastJSArrayWithNoCustomIteration>(o);
}
CastHeapObject<JSReceiver>(implicit context: Context)(o: HeapObject): JSReceiver
labels CastError {
if (IsJSReceiver(o)) return %RawCast<JSReceiver>(o);
goto CastError;
}
CastHeapObject<JSFunction>(implicit context: Context)(o: HeapObject): JSFunction
labels CastError {
if (IsJSFunction(o)) return %RawCast<JSFunction>(o);
goto CastError;
}
macro Cast<A: type>(implicit context: Context)(o: HeapObject): A
labels CastError { labels CastError {
return CastHeapObject<A>(o) otherwise CastError; return CastHeapObject<A>(o) otherwise CastError;
} }
// CastHeapObject allows this default-implementation to be non-recursive. // CastHeapObject allows this default-implementation to be non-recursive.
// Otherwise the generated CSA code might run into infinite recursion. // Otherwise the generated CSA code might run into infinite recursion.
macro Cast<A: type>(o: Object): A macro Cast<A: type>(implicit context: Context)(o: Object): A
labels CastError { labels CastError {
return CastHeapObject<A>(TaggedToHeapObject(o) otherwise CastError) return CastHeapObject<A>(TaggedToHeapObject(o) otherwise CastError)
otherwise CastError; otherwise CastError;
} }
Cast<Smi>(o: Object): Smi Cast<Smi>(o: Object): Smi
labels CastError { labels CastError {
return TaggedToSmi(o) otherwise CastError; return TaggedToSmi(o) otherwise CastError;
} }
Cast<Number>(o: Object): Number Cast<Number>(o: Object): Number
labels CastError { labels CastError {
return TaggedToNumber(o) otherwise CastError; return TaggedToNumber(o) otherwise CastError;
...@@ -774,218 +882,39 @@ Convert<intptr>(r: RawPtr): intptr { ...@@ -774,218 +882,39 @@ Convert<intptr>(r: RawPtr): intptr {
return Signed(r); return Signed(r);
} }
extern macro UnsafeCastNumberToHeapNumber(Number): HeapNumber; macro BranchIf<A: type, B: type>(implicit context: Context)(o: B): never
extern macro UnsafeCastObjectToFixedArrayBase(Object): FixedArrayBase;
extern macro UnsafeCastObjectToFixedArray(Object): FixedArray;
extern macro UnsafeCastObjectToContext(Object): Context;
extern macro UnsafeCastObjectToFixedDoubleArray(Object): FixedDoubleArray;
extern macro UnsafeCastObjectToHeapNumber(Object): HeapNumber;
extern macro UnsafeCastObjectToCallable(Object): Callable;
extern macro UnsafeCastObjectToSmi(Object): Smi;
extern macro UnsafeCastObjectToNumber(Object): Number;
extern macro UnsafeCastObjectToHeapObject(Object): HeapObject;
extern macro UnsafeCastObjectToJSArray(Object): JSArray;
extern macro UnsafeCastObjectToFixedTypedArrayBase(Object): FixedTypedArrayBase;
extern macro UnsafeCastObjectToNumberDictionary(Object): NumberDictionary;
extern macro UnsafeCastObjectToJSReceiver(Object): JSReceiver;
extern macro UnsafeCastObjectToJSObject(Object): JSObject;
extern macro UnsafeCastObjectToMap(Object): Map;
extern macro UnsafeCastObjectToString(Object): String;
macro UnsafeCast<A: type>(n: Number): A;
UnsafeCast<HeapNumber>(n: Number): HeapNumber {
return UnsafeCastNumberToHeapNumber(n);
}
UnsafeCast<Smi>(o: Number): Smi {
return UnsafeCastObjectToSmi(o);
}
macro UnsafeCast<A: type>(o: Object): A;
UnsafeCast<Object>(o: Object): Object {
return o;
}
UnsafeCast<FixedArray>(o: Object): FixedArray {
return UnsafeCastObjectToFixedArray(o);
}
UnsafeCast<FixedDoubleArray>(o: Object): FixedDoubleArray {
return UnsafeCastObjectToFixedDoubleArray(o);
}
UnsafeCast<HeapNumber>(o: Object): HeapNumber {
return UnsafeCastObjectToHeapNumber(o);
}
UnsafeCast<Callable>(o: Object): Callable {
return UnsafeCastObjectToCallable(o);
}
UnsafeCast<Smi>(o: Object): Smi {
return UnsafeCastObjectToSmi(o);
}
UnsafeCast<Number>(o: Object): Number {
return UnsafeCastObjectToNumber(o);
}
UnsafeCast<HeapObject>(o: Object): HeapObject {
return UnsafeCastObjectToHeapObject(o);
}
UnsafeCast<JSArray>(o: Object): JSArray {
return UnsafeCastObjectToJSArray(o);
}
UnsafeCast<FixedTypedArrayBase>(o: Object): FixedTypedArrayBase {
return UnsafeCastObjectToFixedTypedArrayBase(o);
}
UnsafeCast<NumberDictionary>(o: Object): NumberDictionary {
return UnsafeCastObjectToNumberDictionary(o);
}
UnsafeCast<JSReceiver>(o: Object): JSReceiver {
return UnsafeCastObjectToJSReceiver(o);
}
UnsafeCast<JSObject>(o: Object): JSObject {
return UnsafeCastObjectToJSObject(o);
}
UnsafeCast<Map>(o: Object): Map {
return UnsafeCastObjectToMap(o);
}
UnsafeCast<FixedArrayBase>(o: Object): FixedArrayBase {
return UnsafeCastObjectToFixedArrayBase(o);
}
UnsafeCast<Context>(o: Object): Context {
return UnsafeCastObjectToContext(o);
}
UnsafeCast<String>(o: Object): String {
return UnsafeCastObjectToString(o);
}
macro BranchIfJSArgumentsObjectWithLength(implicit context: Context)(o: Object):
never
labels True, False { labels True, False {
const heapObject: HeapObject = Cast<HeapObject>(o) otherwise False; Cast<A>(o) otherwise False;
const map: Map = heapObject.map;
if (IsFastAliasedArgumentsMap(map)) goto True;
if (IsSloppyArgumentsMap(map)) goto True;
if (IsStrictArgumentsMap(map)) goto True;
if (!IsSlowAliasedArgumentsMap(map)) goto False;
goto True; goto True;
} }
UnsafeCast<JSArgumentsObjectWithLength>(implicit context: Context)(o: Object): macro BranchIfNot<A: type, B: type>(implicit context: Context)(o: B): never
JSArgumentsObjectWithLength { labels True, False {
assert(BranchIfJSArgumentsObjectWithLength(o)); Cast<A>(o) otherwise True;
return %RawCast<JSArgumentsObjectWithLength>(o); goto False;
}
Cast<JSArgumentsObjectWithLength>(implicit context: Context)(o: Object):
JSArgumentsObjectWithLength
labels CastError {
if (BranchIfJSArgumentsObjectWithLength(o)) {
return UnsafeCast<JSArgumentsObjectWithLength>(o);
} else {
goto CastError;
}
}
UnsafeCast<FastJSArray>(implicit context: Context)(o: Object): FastJSArray {
assert(BranchIfFastJSArray(o, context));
return %RawCast<FastJSArray>(o);
}
Cast<FastJSArray>(implicit context: Context)(o: Object): FastJSArray
labels CastError {
if (BranchIfFastJSArray(o, context)) {
return UnsafeCast<FastJSArray>(o);
} else {
goto CastError;
}
}
Cast<FastJSArray>(implicit context: Context)(ho: HeapObject): FastJSArray
labels CastError {
if (BranchIfFastJSArray(ho, context)) {
return UnsafeCast<FastJSArray>(ho);
} else {
goto CastError;
}
}
UnsafeCast<FastJSArrayForCopy>(implicit context: Context)(o: Object):
FastJSArrayForCopy {
assert(BranchIfFastJSArrayForCopy(o, context));
return %RawCast<FastJSArrayForCopy>(o);
}
Cast<FastJSArrayForCopy>(implicit context: Context)(o: Object):
FastJSArrayForCopy
labels CastError {
if (BranchIfFastJSArrayForCopy(o, context)) {
return UnsafeCast<FastJSArrayForCopy>(o);
} else {
goto CastError;
}
}
UnsafeCast<FastJSArrayWithNoCustomIteration>(implicit context: Context)(
o: Object): FastJSArrayWithNoCustomIteration {
assert(BranchIfFastJSArrayWithNoCustomIteration(o));
return %RawCast<FastJSArrayWithNoCustomIteration>(o);
}
Cast<FastJSArrayWithNoCustomIteration>(implicit context: Context)(o: Object):
FastJSArrayWithNoCustomIteration labels CastError {
if (BranchIfFastJSArrayWithNoCustomIteration(o)) {
return UnsafeCast<FastJSArrayWithNoCustomIteration>(o);
} else {
goto CastError;
}
}
UnsafeCast<JSFunction>(implicit context: Context)(o: Object): JSFunction {
assert(IsJSFunction(Cast<HeapObject>(o) otherwise unreachable));
return %RawCast<JSFunction>(o);
} }
Cast<JSFunction>(implicit context: Context)(o: Object): JSFunction macro Is<A: type, B: type>(implicit context: Context)(o: B): bool {
labels CastError { return (BranchIf<A, B>(o)) ? true : false;
if (IsJSFunction(Cast<HeapObject>(o) otherwise CastError)) {
return UnsafeCast<JSFunction>(o);
} else {
goto CastError;
}
} }
Cast<Map>(o: Object): Map macro UnsafeCast<A: type>(implicit context: Context)(o: Object): A {
labels CastError { assert(Is<A>(o));
if (IsMap(Cast<HeapObject>(o) otherwise CastError)) { return %RawCast<A>(o);
return UnsafeCast<Map>(o);
} else {
goto CastError;
}
} }
Cast<JSReceiver>(o: Object): JSReceiver UnsafeCast<Object>(o: Object): Object {
labels CastError { return o;
if (IsJSReceiver(Cast<HeapObject>(o) otherwise CastError)) {
return UnsafeCast<JSReceiver>(o);
} else {
goto CastError;
}
} }
const kCOWMap: Map = UnsafeCast<Map>(LoadRoot(kFixedCOWArrayMapRootIndex)); const kCOWMap: Map = %RawCast<Map>(LoadRoot(kFixedCOWArrayMapRootIndex));
const kEmptyFixedArray: FixedArrayBase = const kEmptyFixedArray: FixedArrayBase =
UnsafeCast<FixedArrayBase>(LoadRoot(kEmptyFixedArrayRootIndex)); %RawCast<FixedArrayBase>(LoadRoot(kEmptyFixedArrayRootIndex));
extern macro BranchIfFastJSArray(Object, Context): never extern macro IsPrototypeInitialArrayPrototype(implicit context: Context)(Map):
labels Taken, NotTaken; bool;
extern macro BranchIfFastJSArrayForCopy(Object, Context): never
labels Taken, NotTaken;
extern macro BranchIfFastJSArrayWithNoCustomIteration(
implicit context: Context)(Object): never labels Taken,
NotTaken;
extern macro BranchIfNotFastJSArray(Object, Context): never
labels Taken, NotTaken;
macro BranchIfNotFastJSArrayForCopy(implicit context: Context)(o: Object): never
labels Taken, NotTaken {
BranchIfFastJSArrayForCopy(o, context) otherwise NotTaken, Taken;
}
extern macro IsPrototypeInitialArrayPrototype(Context, Map): bool;
extern macro IsNoElementsProtectorCellInvalid(): bool; extern macro IsNoElementsProtectorCellInvalid(): bool;
extern macro IsArrayIteratorProtectorCellInvalid(): bool;
extern macro IsArraySpeciesProtectorCellInvalid(): bool; extern macro IsArraySpeciesProtectorCellInvalid(): bool;
extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool; extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool;
extern macro IsPromiseSpeciesProtectorCellInvalid(): bool; extern macro IsPromiseSpeciesProtectorCellInvalid(): bool;
...@@ -1176,7 +1105,8 @@ macro TorqueCopyElements( ...@@ -1176,7 +1105,8 @@ macro TorqueCopyElements(
transitioning macro LoadElementNoHole<T: type>(a: JSArray, index: Smi): Object transitioning macro LoadElementNoHole<T: type>(a: JSArray, index: Smi): Object
labels IfHole; labels IfHole;
LoadElementNoHole<FixedArray>(a: JSArray, index: Smi): Object LoadElementNoHole<FixedArray>(implicit context: Context)(
a: JSArray, index: Smi): Object
labels IfHole { labels IfHole {
try { try {
let elements: FixedArray = let elements: FixedArray =
...@@ -1192,7 +1122,8 @@ LoadElementNoHole<FixedArray>(a: JSArray, index: Smi): Object ...@@ -1192,7 +1122,8 @@ LoadElementNoHole<FixedArray>(a: JSArray, index: Smi): Object
} }
} }
LoadElementNoHole<FixedDoubleArray>(a: JSArray, index: Smi): Object LoadElementNoHole<FixedDoubleArray>(implicit context: Context)(
a: JSArray, index: Smi): Object
labels IfHole { labels IfHole {
try { try {
let elements: FixedDoubleArray = let elements: FixedDoubleArray =
...@@ -1212,31 +1143,24 @@ extern macro IsCallable(HeapObject): bool; ...@@ -1212,31 +1143,24 @@ extern macro IsCallable(HeapObject): bool;
extern macro IsJSArray(HeapObject): bool; extern macro IsJSArray(HeapObject): bool;
extern macro IsMap(HeapObject): bool; extern macro IsMap(HeapObject): bool;
extern macro IsJSFunction(HeapObject): bool; extern macro IsJSFunction(HeapObject): bool;
extern macro IsJSObject(HeapObject): bool;
extern macro IsNumberDictionary(HeapObject): bool;
extern macro IsFixedTypedArray(HeapObject): bool;
extern macro IsContext(HeapObject): bool;
extern macro IsJSReceiver(HeapObject): bool; extern macro IsJSReceiver(HeapObject): bool;
extern macro TaggedIsCallable(Object): bool; extern macro TaggedIsCallable(Object): bool;
extern macro IsDetachedBuffer(JSArrayBuffer): bool; extern macro IsDetachedBuffer(JSArrayBuffer): bool;
extern macro IsHeapNumber(HeapObject): bool; extern macro IsHeapNumber(HeapObject): bool;
extern macro IsFixedArray(HeapObject): bool; extern macro IsFixedArray(HeapObject): bool;
extern macro IsNumber(Object): bool; extern macro IsNumber(Object): bool;
extern macro IsJSArrayMap(Map): bool;
extern macro IsExtensibleMap(Map): bool; extern macro IsExtensibleMap(Map): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool; extern macro IsCustomElementsReceiverInstanceType(int32): bool;
extern macro IsFastJSArray(Object, Context): bool;
extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)( extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)(
Object): bool; Object): bool;
extern macro Typeof(Object): Object; extern macro Typeof(Object): Object;
extern macro LoadTargetFromFrame(): JSFunction; extern macro LoadTargetFromFrame(): JSFunction;
macro IsJSReceiver(o: Object): bool {
typeswitch (o) {
case (JSReceiver): {
return true;
}
case (Object): {
return false;
}
}
}
// Return true iff number is NaN. // Return true iff number is NaN.
macro NumberIsNaN(number: Number): bool { macro NumberIsNaN(number: Number): bool {
typeswitch (number) { typeswitch (number) {
...@@ -1250,6 +1174,7 @@ macro NumberIsNaN(number: Number): bool { ...@@ -1250,6 +1174,7 @@ macro NumberIsNaN(number: Number): bool {
} }
} }
extern macro GotoIfForceSlowPath() labels Taken;
extern macro BranchIfToBooleanIsTrue(Object): never extern macro BranchIfToBooleanIsTrue(Object): never
labels Taken, NotTaken; labels Taken, NotTaken;
...@@ -1311,3 +1236,43 @@ struct KeyValuePair { ...@@ -1311,3 +1236,43 @@ struct KeyValuePair {
key: Object; key: Object;
value: Object; value: Object;
} }
// Macro definitions for compatibility that expose functionality to the CSA
// using "legacy" APIs. In Torque code, these should not be used.
macro IsFastJSArray(o: Object, context: Context): bool {
try {
// Long-term, it's likely not a good idea to have this slow-path test here,
// since it fundamentally breaks the type system.
GotoIfForceSlowPath() otherwise ForceSlow;
}
label ForceSlow {
return false;
}
return Is<FastJSArray>(o);
}
macro BranchIfFastJSArray(o: Object, context: Context): never
labels True, False {
// Long-term, it's likely not a good idea to have this slow-path test here,
// since it fundamentally breaks the type system.
GotoIfForceSlowPath() otherwise False;
BranchIf<FastJSArray>(o) otherwise True, False;
}
macro BranchIfNotFastJSArray(o: Object, context: Context): never
labels True, False {
BranchIfNot<FastJSArray>(o) otherwise True, False;
}
macro BranchIfFastJSArrayForCopy(o: Object, context: Context): never
labels True, False {
// Long-term, it's likely not a good idea to have this slow-path test here,
// since it fundamentally breaks the type system.
GotoIfForceSlowPath() otherwise False;
BranchIf<FastJSArrayForCopy>(o) otherwise True, False;
}
macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool {
return Is<FastJSArrayWithNoCustomIteration>(o);
}
...@@ -148,7 +148,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) { ...@@ -148,7 +148,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
Label fast(this); Label fast(this);
Label runtime(this); Label runtime(this);
Label object_push_pre(this), object_push(this), double_push(this); Label object_push_pre(this), object_push(this), double_push(this);
BranchIfFastJSArray(a(), context(), &fast, &runtime); BranchIfFastJSArray(CAST(a()), context(), &fast, &runtime);
BIND(&fast); BIND(&fast);
{ {
......
...@@ -21,7 +21,7 @@ namespace object { ...@@ -21,7 +21,7 @@ namespace object {
// Bail out if ToPropertyKey will attempt to load and call // Bail out if ToPropertyKey will attempt to load and call
// Symbol.toPrimitive, toString, and valueOf, which could // Symbol.toPrimitive, toString, and valueOf, which could
// invalidate assumptions about the iterable. // invalidate assumptions about the iterable.
if (IsJSReceiver(pair.key)) goto IfSlow; if (Is<JSReceiver>(pair.key)) goto IfSlow;
CreateDataProperty(result, pair.key, pair.value); CreateDataProperty(result, pair.key, pair.value);
} }
return result; return result;
......
...@@ -16,6 +16,18 @@ namespace typed_array { ...@@ -16,6 +16,18 @@ namespace typed_array {
type LoadFn = builtin(Context, JSTypedArray, Smi) => Object; type LoadFn = builtin(Context, JSTypedArray, Smi) => Object;
type StoreFn = builtin(Context, JSTypedArray, Smi, Object) => Object; type StoreFn = builtin(Context, JSTypedArray, Smi, Object) => Object;
// These UnsafeCast specializations are necessary becuase there is no
// way to definitively test whether an Object is a Torque function
// with a specific signature, and the default UnsafeCast implementation
// would try to check this through an assert(Is<>), so the test
// is bypassed in this specialization.
UnsafeCast<LoadFn>(implicit context: Context)(o: Object): LoadFn {
return %RawCast<LoadFn>(o);
}
UnsafeCast<StoreFn>(implicit context: Context)(o: Object): StoreFn {
return %RawCast<StoreFn>(o);
}
macro KindForArrayType<T: type>(): constexpr ElementsKind; macro KindForArrayType<T: type>(): constexpr ElementsKind;
KindForArrayType<FixedUint8Array>(): constexpr ElementsKind { KindForArrayType<FixedUint8Array>(): constexpr ElementsKind {
return UINT8_ELEMENTS; return UINT8_ELEMENTS;
......
...@@ -1037,90 +1037,6 @@ void CodeStubAssembler::BranchIfJSReceiver(Node* object, Label* if_true, ...@@ -1037,90 +1037,6 @@ void CodeStubAssembler::BranchIfJSReceiver(Node* object, Label* if_true,
Branch(IsJSReceiver(object), if_true, if_false); Branch(IsJSReceiver(object), if_true, if_false);
} }
TNode<BoolT> CodeStubAssembler::IsFastJSArray(SloppyTNode<Object> object,
SloppyTNode<Context> context) {
Label if_true(this), if_false(this, Label::kDeferred), exit(this);
BranchIfFastJSArray(object, context, &if_true, &if_false);
TVARIABLE(BoolT, var_result);
BIND(&if_true);
{
var_result = Int32TrueConstant();
Goto(&exit);
}
BIND(&if_false);
{
var_result = Int32FalseConstant();
Goto(&exit);
}
BIND(&exit);
return var_result.value();
}
void CodeStubAssembler::BranchIfFastJSArrayWithNoCustomIteration(
TNode<Context> context, TNode<Object> object, Label* if_true,
Label* if_false) {
Label if_fast(this);
BranchIfFastJSArray(object, context, &if_fast, if_false, true);
BIND(&if_fast);
{
// Check that the Array.prototype hasn't been modified in a way that would
// affect iteration.
Node* protector_cell = LoadRoot(RootIndex::kArrayIteratorProtector);
DCHECK(isolate()->heap()->array_iterator_protector()->IsPropertyCell());
Branch(
WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)),
if_true, if_false);
}
}
TNode<BoolT> CodeStubAssembler::IsFastJSArrayWithNoCustomIteration(
TNode<Context> context, TNode<Object> object) {
Label if_false(this, Label::kDeferred), exit(this);
TVARIABLE(BoolT, var_result, Int32TrueConstant());
BranchIfFastJSArrayWithNoCustomIteration(context, object, &exit, &if_false);
BIND(&if_false);
{
var_result = Int32FalseConstant();
Goto(&exit);
}
BIND(&exit);
return var_result.value();
}
void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
Label* if_true, Label* if_false,
bool iteration_only) {
GotoIfForceSlowPath(if_false);
// Bailout if receiver is a Smi.
GotoIf(TaggedIsSmi(object), if_false);
Node* map = LoadMap(object);
GotoIfNot(IsJSArrayMap(map), if_false);
// Bailout if receiver has slow elements.
Node* elements_kind = LoadMapElementsKind(map);
GotoIfNot(IsFastElementsKind(elements_kind), if_false);
// Verify that our prototype is the initial array prototype.
GotoIfNot(IsPrototypeInitialArrayPrototype(context, map), if_false);
if (iteration_only) {
// If we are only iterating over the array, there is no need to check
// the NoElements protector if the array is not holey.
GotoIfNot(IsHoleyFastElementsKind(elements_kind), if_true);
}
Branch(IsNoElementsProtectorCellInvalid(), if_false, if_true);
}
void CodeStubAssembler::BranchIfFastJSArrayForCopy(Node* object, Node* context,
Label* if_true,
Label* if_false) {
GotoIf(IsArraySpeciesProtectorCellInvalid(), if_false);
BranchIfFastJSArray(object, context, if_true, if_false);
}
void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) { void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) {
#ifdef V8_ENABLE_FORCE_SLOW_PATH #ifdef V8_ENABLE_FORCE_SLOW_PATH
Node* const force_slow_path_addr = Node* const force_slow_path_addr =
...@@ -5958,6 +5874,13 @@ TNode<BoolT> CodeStubAssembler::IsNoElementsProtectorCellInvalid() { ...@@ -5958,6 +5874,13 @@ TNode<BoolT> CodeStubAssembler::IsNoElementsProtectorCellInvalid() {
return WordEqual(cell_value, invalid); return WordEqual(cell_value, invalid);
} }
TNode<BoolT> CodeStubAssembler::IsArrayIteratorProtectorCellInvalid() {
Node* invalid = SmiConstant(Isolate::kProtectorInvalid);
Node* cell = LoadRoot(RootIndex::kArrayIteratorProtector);
Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
return WordEqual(cell_value, invalid);
}
TNode<BoolT> CodeStubAssembler::IsPromiseResolveProtectorCellInvalid() { TNode<BoolT> CodeStubAssembler::IsPromiseResolveProtectorCellInvalid() {
Node* invalid = SmiConstant(Isolate::kProtectorInvalid); Node* invalid = SmiConstant(Isolate::kProtectorInvalid);
Node* cell = LoadRoot(RootIndex::kPromiseResolveProtector); Node* cell = LoadRoot(RootIndex::kPromiseResolveProtector);
......
...@@ -326,105 +326,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -326,105 +326,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return CAST(heap_object); return CAST(heap_object);
} }
TNode<HeapNumber> UnsafeCastNumberToHeapNumber(TNode<Number> p_n) {
return CAST(p_n);
}
TNode<FixedArrayBase> UnsafeCastObjectToFixedArrayBase(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<FixedArray> UnsafeCastObjectToFixedArray(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<Context> UnsafeCastObjectToContext(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<FixedDoubleArray> UnsafeCastObjectToFixedDoubleArray(
TNode<Object> p_o) {
return CAST(p_o);
}
TNode<HeapNumber> UnsafeCastObjectToHeapNumber(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<HeapObject> UnsafeCastObjectToCallable(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<Smi> UnsafeCastObjectToSmi(TNode<Object> p_o) { return CAST(p_o); }
TNode<Number> UnsafeCastObjectToNumber(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<HeapObject> UnsafeCastObjectToHeapObject(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSArray> UnsafeCastObjectToJSArray(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<FixedTypedArrayBase> UnsafeCastObjectToFixedTypedArrayBase(
TNode<Object> p_o) {
return CAST(p_o);
}
TNode<Object> UnsafeCastObjectToCompareBuiltinFn(TNode<Object> p_o) {
return p_o;
}
TNode<Object> UnsafeCastObjectToLoadFn(TNode<Object> p_o) { return p_o; }
TNode<Object> UnsafeCastObjectToStoreFn(TNode<Object> p_o) { return p_o; }
TNode<Object> UnsafeCastObjectToCanUseSameAccessorFn(TNode<Object> p_o) {
return p_o;
}
TNode<NumberDictionary> UnsafeCastObjectToNumberDictionary(
TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSReceiver> UnsafeCastObjectToJSReceiver(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSObject> UnsafeCastObjectToJSObject(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<Map> UnsafeCastObjectToMap(TNode<Object> p_o) { return CAST(p_o); }
TNode<String> UnsafeCastObjectToString(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSArgumentsObjectWithLength> RawCastObjectToJSArgumentsObjectWithLength(
TNode<Object> p_o) {
return TNode<JSArgumentsObjectWithLength>::UncheckedCast(p_o);
}
TNode<JSArray> RawCastObjectToFastJSArray(TNode<Object> p_o) {
return TNode<JSArray>::UncheckedCast(p_o);
}
TNode<JSArray> RawCastObjectToFastJSArrayForCopy(TNode<Object> p_o) {
return TNode<JSArray>::UncheckedCast(p_o);
}
TNode<JSArray> RawCastObjectToFastJSArrayWithNoCustomIteration(
TNode<Object> p_o) {
return TNode<JSArray>::UncheckedCast(p_o);
}
TNode<JSFunction> RawCastObjectToJSFunction(TNode<Object> p_o) {
return TNode<JSFunction>::UncheckedCast(p_o);
}
Node* MatchesParameterMode(Node* value, ParameterMode mode); Node* MatchesParameterMode(Node* value, ParameterMode mode);
#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ #define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
...@@ -804,19 +705,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -804,19 +705,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void BranchIfJSReceiver(Node* object, Label* if_true, Label* if_false); void BranchIfJSReceiver(Node* object, Label* if_true, Label* if_false);
void BranchIfFastJSArray(Node* object, Node* context, Label* if_true,
Label* if_false, bool iteration_only = false);
void BranchIfNotFastJSArray(Node* object, Node* context, Label* if_true,
Label* if_false) {
BranchIfFastJSArray(object, context, if_false, if_true);
}
void BranchIfFastJSArrayForCopy(Node* object, Node* context, Label* if_true,
Label* if_false);
void BranchIfFastJSArrayWithNoCustomIteration(TNode<Context> context,
TNode<Object> object,
Label* if_true,
Label* if_false);
// Branches to {if_true} when --force-slow-path flag has been passed. // Branches to {if_true} when --force-slow-path flag has been passed.
// It's used for testing to ensure that slow path implementation behave // It's used for testing to ensure that slow path implementation behave
// equivalent to corresponding fast paths (where applicable). // equivalent to corresponding fast paths (where applicable).
...@@ -2022,6 +1910,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2022,6 +1910,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsAllocationSite(SloppyTNode<HeapObject> object); TNode<BoolT> IsAllocationSite(SloppyTNode<HeapObject> object);
TNode<BoolT> IsAnyHeapNumber(SloppyTNode<HeapObject> object); TNode<BoolT> IsAnyHeapNumber(SloppyTNode<HeapObject> object);
TNode<BoolT> IsNoElementsProtectorCellInvalid(); TNode<BoolT> IsNoElementsProtectorCellInvalid();
TNode<BoolT> IsArrayIteratorProtectorCellInvalid();
TNode<BoolT> IsBigIntInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsBigIntInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsBigInt(SloppyTNode<HeapObject> object); TNode<BoolT> IsBigInt(SloppyTNode<HeapObject> object);
TNode<BoolT> IsBoolean(SloppyTNode<HeapObject> object); TNode<BoolT> IsBoolean(SloppyTNode<HeapObject> object);
...@@ -2039,10 +1928,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2039,10 +1928,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsExtensibleMap(SloppyTNode<Map> map); TNode<BoolT> IsExtensibleMap(SloppyTNode<Map> map);
TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map); TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map);
TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsFastJSArray(SloppyTNode<Object> object,
SloppyTNode<Context> context);
TNode<BoolT> IsFastJSArrayWithNoCustomIteration(TNode<Context> context,
TNode<Object> object);
TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object); TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);
TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object); TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object);
TNode<BoolT> IsContext(SloppyTNode<HeapObject> object); TNode<BoolT> IsContext(SloppyTNode<HeapObject> object);
......
...@@ -244,11 +244,15 @@ TEST(TestForLoop) { ...@@ -244,11 +244,15 @@ TEST(TestForLoop) {
} }
TEST(TestTypeswitch) { TEST(TestTypeswitch) {
Isolate* isolate(CcTest::InitIsolateOnce()); CcTest::InitializeVM();
Isolate* isolate(CcTest::i_isolate());
i::HandleScope scope(isolate);
Handle<Context> context =
Utils::OpenHandle(*v8::Isolate::GetCurrent()->GetCurrentContext());
CodeAssemblerTester asm_tester(isolate, 0); CodeAssemblerTester asm_tester(isolate, 0);
TestTorqueAssembler m(asm_tester.state()); TestTorqueAssembler m(asm_tester.state());
{ {
m.TestTypeswitch(); m.TestTypeswitch(m.UncheckedCast<Context>(m.HeapConstant(context)));
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
...@@ -256,11 +260,15 @@ TEST(TestTypeswitch) { ...@@ -256,11 +260,15 @@ TEST(TestTypeswitch) {
} }
TEST(TestGenericOverload) { TEST(TestGenericOverload) {
Isolate* isolate(CcTest::InitIsolateOnce()); CcTest::InitializeVM();
Isolate* isolate(CcTest::i_isolate());
i::HandleScope scope(isolate);
Handle<Context> context =
Utils::OpenHandle(*v8::Isolate::GetCurrent()->GetCurrentContext());
CodeAssemblerTester asm_tester(isolate, 0); CodeAssemblerTester asm_tester(isolate, 0);
TestTorqueAssembler m(asm_tester.state()); TestTorqueAssembler m(asm_tester.state());
{ {
m.TestGenericOverload(); m.TestGenericOverload(m.UncheckedCast<Context>(m.HeapConstant(context)));
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
...@@ -352,11 +360,15 @@ TEST(TestCatch3) { ...@@ -352,11 +360,15 @@ TEST(TestCatch3) {
} }
TEST(TestLookup) { TEST(TestLookup) {
Isolate* isolate(CcTest::InitIsolateOnce()); CcTest::InitializeVM();
Isolate* isolate(CcTest::i_isolate());
i::HandleScope scope(isolate);
Handle<Context> context =
Utils::OpenHandle(*v8::Isolate::GetCurrent()->GetCurrentContext());
CodeAssemblerTester asm_tester(isolate, 0); CodeAssemblerTester asm_tester(isolate, 0);
TestTorqueAssembler m(asm_tester.state()); TestTorqueAssembler m(asm_tester.state());
{ {
m.TestQualifiedAccess(); m.TestQualifiedAccess(m.UncheckedCast<Context>(m.HeapConstant(context)));
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
......
...@@ -174,7 +174,7 @@ namespace test { ...@@ -174,7 +174,7 @@ namespace test {
return x + 2; return x + 2;
} }
macro TestFunctionPointers(context: Context): Boolean { macro TestFunctionPointers(implicit context: Context)(): Boolean {
let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1; let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1;
check(fptr(context, 42) == 43); check(fptr(context, 42) == 43);
fptr = TestHelperPlus2; fptr = TestHelperPlus2;
...@@ -182,7 +182,7 @@ namespace test { ...@@ -182,7 +182,7 @@ namespace test {
return True; return True;
} }
macro TestVariableRedeclaration(context: Context): Boolean { macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
let var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1; let var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
let var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0; let var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
return True; return True;
...@@ -208,11 +208,11 @@ namespace test { ...@@ -208,11 +208,11 @@ namespace test {
return x; return x;
} }
macro TestUnsafeCast(c: Context, n: Number): Boolean { macro TestUnsafeCast(implicit context: Context)(n: Number): Boolean {
if (TaggedIsSmi(n)) { if (TaggedIsSmi(n)) {
let m: Smi = UnsafeCast<Smi>(n); let m: Smi = UnsafeCast<Smi>(n);
check(TestHelperPlus1(c, m) == 11); check(TestHelperPlus1(context, m) == 11);
return True; return True;
} }
return False; return False;
...@@ -223,7 +223,7 @@ namespace test { ...@@ -223,7 +223,7 @@ namespace test {
check(Convert<intptr>(-0xffff) == -65535); check(Convert<intptr>(-0xffff) == -65535);
} }
macro TestLargeIntegerLiterals(c: Context) { macro TestLargeIntegerLiterals(implicit c: Context)() {
let x: int32 = 0x40000000; let x: int32 = 0x40000000;
let y: int32 = 0x7fffffff; let y: int32 = 0x7fffffff;
} }
...@@ -278,11 +278,11 @@ namespace test { ...@@ -278,11 +278,11 @@ namespace test {
return i.i; return i.i;
} }
macro TestStruct2(): TestStructA { macro TestStruct2(implicit context: Context)(): TestStructA {
return TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 27, 31}; return TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 27, 31};
} }
macro TestStruct3(): TestStructA { macro TestStruct3(implicit context: Context)(): TestStructA {
let a: TestStructA = let a: TestStructA =
TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 13, 5}; TestStructA{UnsafeCast<FixedArray>(kEmptyFixedArray), 13, 5};
let b: TestStructA = a; let b: TestStructA = a;
...@@ -304,7 +304,7 @@ namespace test { ...@@ -304,7 +304,7 @@ namespace test {
y: TestStructA; y: TestStructA;
} }
macro TestStruct4(): TestStructC { macro TestStruct4(implicit context: Context)(): TestStructC {
return TestStructC{TestStruct2(), TestStruct2()}; return TestStructC{TestStruct2(), TestStruct2()};
} }
...@@ -419,7 +419,9 @@ namespace test { ...@@ -419,7 +419,9 @@ namespace test {
} }
} }
macro TypeswitchExample(x: Number | FixedArray): int32 { type NumberOrFixedArray = Number | FixedArray;
macro TypeswitchExample(implicit context: Context)(x: NumberOrFixedArray):
int32 {
let result: int32 = 0; let result: int32 = 0;
typeswitch (IncrementIfSmi(x)) { typeswitch (IncrementIfSmi(x)) {
case (x: FixedArray): { case (x: FixedArray): {
...@@ -447,7 +449,7 @@ namespace test { ...@@ -447,7 +449,7 @@ namespace test {
return result; return result;
} }
macro TestTypeswitch() { macro TestTypeswitch(implicit context: Context)() {
check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26); check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26);
const a: FixedArray = AllocateZeroedFixedArray(3); const a: FixedArray = AllocateZeroedFixedArray(3);
check(TypeswitchExample(a) == 13); check(TypeswitchExample(a) == 13);
...@@ -461,7 +463,7 @@ namespace test { ...@@ -461,7 +463,7 @@ namespace test {
return o + 1; return o + 1;
} }
macro TestGenericOverload() { macro TestGenericOverload(implicit context: Context)() {
const xSmi: Smi = 5; const xSmi: Smi = 5;
const xObject: Object = xSmi; const xObject: Object = xSmi;
check(ExampleGenericOverload<Smi>(xSmi) == 6); check(ExampleGenericOverload<Smi>(xSmi) == 6);
...@@ -599,12 +601,12 @@ namespace test { ...@@ -599,12 +601,12 @@ namespace test {
} }
} }
macro TestQualifiedAccess() { macro TestQualifiedAccess(implicit context: Context)() {
let s: Smi = 0; let s: Smi = 0;
check(!array::IsJSArray(s)); check(!array::IsJSArray(s));
} }
macro TestCatch1(context: Context): Smi { macro TestCatch1(implicit context: Context)(): Smi {
let r: Smi = 0; let r: Smi = 0;
try { try {
ThrowTypeError(context, kInvalidArrayLength); ThrowTypeError(context, kInvalidArrayLength);
...@@ -614,29 +616,29 @@ namespace test { ...@@ -614,29 +616,29 @@ namespace test {
} }
} }
macro TestCatch2Wrapper(context: Context): never { macro TestCatch2Wrapper(implicit context: Context)(): never {
ThrowTypeError(context, kInvalidArrayLength); ThrowTypeError(context, kInvalidArrayLength);
} }
macro TestCatch2(context: Context): Smi { macro TestCatch2(implicit context: Context)(): Smi {
let r: Smi = 0; let r: Smi = 0;
try { try {
TestCatch2Wrapper(context); TestCatch2Wrapper();
} catch (e) { } catch (e) {
r = 2; r = 2;
return r; return r;
} }
} }
macro TestCatch3WrapperWithLabel(context: Context): never macro TestCatch3WrapperWithLabel(implicit context: Context)(): never
labels Abort { labels Abort {
ThrowTypeError(context, kInvalidArrayLength); ThrowTypeError(context, kInvalidArrayLength);
} }
macro TestCatch3(context: Context): Smi { macro TestCatch3(implicit context: Context)(): Smi {
let r: Smi = 0; let r: Smi = 0;
try { try {
TestCatch3WrapperWithLabel(context) otherwise Abort; TestCatch3WrapperWithLabel() otherwise Abort;
} }
label Abort { label Abort {
return -1; return -1;
......
...@@ -257,25 +257,19 @@ namespace array { ...@@ -257,25 +257,19 @@ namespace array {
return kSuccess; return kSuccess;
} }
extern macro UnsafeCastObjectToCompareBuiltinFn(Object): CompareBuiltinFn; UnsafeCast<CompareBuiltinFn>(implicit context: Context)(o: Object):
UnsafeCast<CompareBuiltinFn>(o: Object): CompareBuiltinFn { CompareBuiltinFn {
return UnsafeCastObjectToCompareBuiltinFn(o); return %RawCast<CompareBuiltinFn>(o);
} }
UnsafeCast<LoadFn>(implicit context: Context)(o: Object): LoadFn {
extern macro UnsafeCastObjectToLoadFn(Object): LoadFn; return %RawCast<LoadFn>(o);
UnsafeCast<LoadFn>(o: Object): LoadFn {
return UnsafeCastObjectToLoadFn(o);
} }
UnsafeCast<StoreFn>(implicit context: Context)(o: Object): StoreFn {
extern macro UnsafeCastObjectToStoreFn(Object): StoreFn; return %RawCast<StoreFn>(o);
UnsafeCast<StoreFn>(o: Object): StoreFn {
return UnsafeCastObjectToStoreFn(o);
} }
UnsafeCast<CanUseSameAccessorFn>(implicit context: Context)(o: Object):
extern macro UnsafeCastObjectToCanUseSameAccessorFn(Object): CanUseSameAccessorFn {
CanUseSameAccessorFn; return %RawCast<CanUseSameAccessorFn>(o);
UnsafeCast<CanUseSameAccessorFn>(o: Object): CanUseSameAccessorFn {
return UnsafeCastObjectToCanUseSameAccessorFn(o);
} }
builtin SortCompareDefault( builtin SortCompareDefault(
...@@ -375,7 +369,8 @@ namespace array { ...@@ -375,7 +369,8 @@ namespace array {
// might have occurred. This means we cannot leave any pointer to the elements // might have occurred. This means we cannot leave any pointer to the elements
// backing store on the stack (since it would point to the filler object). // backing store on the stack (since it would point to the filler object).
// TODO(v8:7995): Remove reloading once left-trimming is removed. // TODO(v8:7995): Remove reloading once left-trimming is removed.
macro ReloadElements(sortState: FixedArray): HeapObject { macro ReloadElements(implicit context: Context)(sortState: FixedArray):
HeapObject {
const receiver: JSReceiver = GetReceiver(sortState); const receiver: JSReceiver = GetReceiver(sortState);
if (sortState[kAccessorIdx] == kGenericElementsAccessorId) return receiver; if (sortState[kAccessorIdx] == kGenericElementsAccessorId) return receiver;
...@@ -383,35 +378,40 @@ namespace array { ...@@ -383,35 +378,40 @@ namespace array {
return object.elements; return object.elements;
} }
macro GetInitialReceiverLength(sortState: FixedArray): Number { macro GetInitialReceiverLength(implicit context:
Context)(sortState: FixedArray): Number {
return UnsafeCast<Number>(sortState[kInitialReceiverLengthIdx]); return UnsafeCast<Number>(sortState[kInitialReceiverLengthIdx]);
} }
macro GetLoadFn(sortState: FixedArray): LoadFn { macro GetLoadFn(implicit context: Context)(sortState: FixedArray): LoadFn {
return UnsafeCast<LoadFn>(sortState[kLoadFnIdx]); return UnsafeCast<LoadFn>(sortState[kLoadFnIdx]);
} }
macro GetStoreFn(sortState: FixedArray): StoreFn { macro GetStoreFn(implicit context: Context)(sortState: FixedArray): StoreFn {
return UnsafeCast<StoreFn>(sortState[kStoreFnIdx]); return UnsafeCast<StoreFn>(sortState[kStoreFnIdx]);
} }
macro GetCanUseSameAccessorFn(sortState: FixedArray): CanUseSameAccessorFn { macro GetCanUseSameAccessorFn(implicit context: Context)(
sortState: FixedArray): CanUseSameAccessorFn {
return UnsafeCast<CanUseSameAccessorFn>( return UnsafeCast<CanUseSameAccessorFn>(
sortState[kCanUseSameAccessorFnIdx]); sortState[kCanUseSameAccessorFnIdx]);
} }
macro GetReceiver(sortState: FixedArray): JSReceiver { macro GetReceiver(implicit context: Context)(sortState: FixedArray):
JSReceiver {
return UnsafeCast<JSReceiver>(sortState[kReceiverIdx]); return UnsafeCast<JSReceiver>(sortState[kReceiverIdx]);
} }
// Returns the temporary array without changing its size. // Returns the temporary array without changing its size.
macro GetTempArray(sortState: FixedArray): FixedArray { macro GetTempArray(implicit context: Context)(sortState: FixedArray):
FixedArray {
return UnsafeCast<FixedArray>(sortState[kTempArrayIdx]); return UnsafeCast<FixedArray>(sortState[kTempArrayIdx]);
} }
// Re-loading the stack-size is done in a few places. The small macro allows // Re-loading the stack-size is done in a few places. The small macro allows
// for easier invariant checks at all use sites. // for easier invariant checks at all use sites.
macro GetPendingRunsSize(sortState: FixedArray): Smi { macro GetPendingRunsSize(implicit context: Context)(sortState: FixedArray):
Smi {
assert(TaggedIsSmi(sortState[kPendingRunsSizeIdx])); assert(TaggedIsSmi(sortState[kPendingRunsSizeIdx]));
const stackSize: Smi = UnsafeCast<Smi>(sortState[kPendingRunsSizeIdx]); const stackSize: Smi = UnsafeCast<Smi>(sortState[kPendingRunsSizeIdx]);
...@@ -423,7 +423,8 @@ namespace array { ...@@ -423,7 +423,8 @@ namespace array {
sortState[kPendingRunsSizeIdx] = value; sortState[kPendingRunsSizeIdx] = value;
} }
macro GetPendingRunBase(pendingRuns: FixedArray, run: Smi): Smi { macro GetPendingRunBase(implicit context:
Context)(pendingRuns: FixedArray, run: Smi): Smi {
return UnsafeCast<Smi>(pendingRuns[run << 1]); return UnsafeCast<Smi>(pendingRuns[run << 1]);
} }
...@@ -431,7 +432,8 @@ namespace array { ...@@ -431,7 +432,8 @@ namespace array {
pendingRuns[run << 1] = value; pendingRuns[run << 1] = value;
} }
macro GetPendingRunLength(pendingRuns: FixedArray, run: Smi): Smi { macro GetPendingRunLength(implicit context: Context)(
pendingRuns: FixedArray, run: Smi): Smi {
return UnsafeCast<Smi>(pendingRuns[(run << 1) + 1]); return UnsafeCast<Smi>(pendingRuns[(run << 1) + 1]);
} }
...@@ -439,7 +441,8 @@ namespace array { ...@@ -439,7 +441,8 @@ namespace array {
pendingRuns[(run << 1) + 1] = value; pendingRuns[(run << 1) + 1] = value;
} }
macro PushRun(sortState: FixedArray, base: Smi, length: Smi) { macro PushRun(implicit context:
Context)(sortState: FixedArray, base: Smi, length: Smi) {
assert(GetPendingRunsSize(sortState) < kMaxMergePending); assert(GetPendingRunsSize(sortState) < kMaxMergePending);
const stackSize: Smi = GetPendingRunsSize(sortState); const stackSize: Smi = GetPendingRunsSize(sortState);
...@@ -454,7 +457,8 @@ namespace array { ...@@ -454,7 +457,8 @@ namespace array {
// Returns the temporary array and makes sure that it is big enough. // Returns the temporary array and makes sure that it is big enough.
// TODO(szuend): Implement a better re-size strategy. // TODO(szuend): Implement a better re-size strategy.
macro GetTempArray(sortState: FixedArray, requestedSize: Smi): FixedArray { macro GetTempArray(implicit context: Context)(
sortState: FixedArray, requestedSize: Smi): FixedArray {
const minSize: Smi = SmiMax(kSortStateTempSize, requestedSize); const minSize: Smi = SmiMax(kSortStateTempSize, requestedSize);
const currentSize: Smi = UnsafeCast<Smi>(sortState[kTempArraySizeIdx]); const currentSize: Smi = UnsafeCast<Smi>(sortState[kTempArraySizeIdx]);
...@@ -471,7 +475,8 @@ namespace array { ...@@ -471,7 +475,8 @@ namespace array {
} }
// This macro jumps to the Bailout label iff kBailoutStatus is kFailure. // This macro jumps to the Bailout label iff kBailoutStatus is kFailure.
macro EnsureSuccess(sortState: FixedArray) labels Bailout { macro EnsureSuccess(implicit context:
Context)(sortState: FixedArray) labels Bailout {
const status: Smi = UnsafeCast<Smi>(sortState[kBailoutStatusIdx]); const status: Smi = UnsafeCast<Smi>(sortState[kBailoutStatusIdx]);
if (status == kFailure) goto Bailout; if (status == kFailure) goto Bailout;
} }
...@@ -882,8 +887,8 @@ namespace array { ...@@ -882,8 +887,8 @@ namespace array {
} }
} }
macro LoadElementsOrTempArray(useTempArray: Boolean, sortState: FixedArray): macro LoadElementsOrTempArray(implicit context: Context)(
HeapObject { useTempArray: Boolean, sortState: FixedArray): HeapObject {
return useTempArray == True ? GetTempArray(sortState) : return useTempArray == True ? GetTempArray(sortState) :
ReloadElements(sortState); ReloadElements(sortState);
} }
...@@ -1535,7 +1540,8 @@ namespace array { ...@@ -1535,7 +1540,8 @@ namespace array {
} }
// Returns true iff run_length(n - 2) > run_length(n - 1) + run_length(n). // Returns true iff run_length(n - 2) > run_length(n - 1) + run_length(n).
macro RunInvariantEstablished(pendingRuns: FixedArray, n: Smi): bool { macro RunInvariantEstablished(implicit context: Context)(
pendingRuns: FixedArray, n: Smi): bool {
if (n < 2) return true; if (n < 2) return true;
const runLengthN: Smi = GetPendingRunLength(pendingRuns, n); const runLengthN: Smi = GetPendingRunLength(pendingRuns, n);
......
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