1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5type Arguments constexpr 'CodeStubArguments*';
6type void generates 'void';
7type never generates 'void';
8
9type Tagged generates 'TNode<Object>';
10type Smi extends Tagged generates 'TNode<Smi>';
11type HeapObject extends Tagged generates 'TNode<HeapObject>';
12type Object = Smi|HeapObject;
13type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
14type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t';
15type int64 generates 'TNode<Int64T>' constexpr 'int64_t';
16type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t';
17type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t';
18type float32 generates 'TNode<Float32T>' constexpr 'float';
19type float64 generates 'TNode<Float64T>' constexpr 'double';
20type bool generates 'TNode<BoolT>' constexpr 'bool';
21type string constexpr 'const char*';
22
23type int31 extends int32 generates 'TNode<Int32T>' constexpr 'int31_t';
24type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
25type AbstractCode extends HeapObject generates 'TNode<AbstractCode>';
26type Code extends AbstractCode generates 'TNode<Code>';
27type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
28type Context extends HeapObject generates 'TNode<Context>';
29type String extends HeapObject generates 'TNode<String>';
30type Oddball extends HeapObject generates 'TNode<Oddball>';
31type HeapNumber extends HeapObject generates 'TNode<HeapNumber>';
32type Number = Smi|HeapNumber;
33type BigInt extends HeapObject generates 'TNode<BigInt>';
34type Numeric = Number|BigInt;
35type Boolean extends Oddball generates 'TNode<Oddball>';
36type JSProxy extends JSReceiver generates 'TNode<JSProxy>';
37type JSObject extends JSReceiver generates 'TNode<JSObject>';
38type JSArray extends JSObject generates 'TNode<JSArray>';
39type JSFunction extends JSObject generates 'TNode<JSFunction>';
40type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>';
41type Callable = JSFunction|JSBoundFunction|JSProxy;
42type Map extends HeapObject generates 'TNode<Map>';
43type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
44type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
45type FixedDoubleArray extends FixedArrayBase generates
46'TNode<FixedDoubleArray>';
47type FixedTypedArrayBase extends FixedArrayBase generates
48'TNode<FixedTypedArrayBase>';
49type FixedTypedArray extends FixedTypedArrayBase generates
50'TNode<FixedTypedArray>';
51type NumberDictionary extends HeapObject generates 'TNode<NumberDictionary>';
52
53type JSArrayBuffer extends JSObject generates 'TNode<JSArrayBuffer>';
54type JSArrayBufferView extends JSObject generates 'TNode<JSArrayBufferView>';
55type JSTypedArray extends JSArrayBufferView generates 'TNode<JSTypedArray>';
56type JSDataView extends JSArrayBufferView generates 'TNode<JSDataView>';
57
58type InstanceType generates 'TNode<Int32T>' constexpr 'InstanceType';
59type ElementsKind generates 'TNode<Int32T>' constexpr 'ElementsKind';
60type LanguageMode generates 'TNode<Smi>' constexpr 'LanguageMode';
61type ExtractFixedArrayFlags generates
62'TNode<Smi>' constexpr 'ExtractFixedArrayFlags';
63type ParameterMode generates 'TNode<Int32T>' constexpr 'ParameterMode';
64type RootListIndex generates 'TNode<Int32T>' constexpr 'Heap::RootListIndex';
65type WriteBarrierMode generates 'TNode<Int32T>' constexpr 'WriteBarrierMode';
66
67type MessageTemplate constexpr 'MessageTemplate::Template';
68
69type ToIntegerTruncationMode constexpr 'ToIntegerTruncationMode';
70
71const NO_ELEMENTS: constexpr ElementsKind generates 'NO_ELEMENTS';
72
73const PACKED_SMI_ELEMENTS: constexpr ElementsKind generates
74'PACKED_SMI_ELEMENTS';
75const HOLEY_SMI_ELEMENTS: constexpr ElementsKind generates 'HOLEY_SMI_ELEMENTS';
76const PACKED_ELEMENTS: constexpr ElementsKind generates 'PACKED_ELEMENTS';
77const HOLEY_ELEMENTS: constexpr ElementsKind generates 'HOLEY_ELEMENTS';
78const PACKED_DOUBLE_ELEMENTS: constexpr ElementsKind generates
79'PACKED_DOUBLE_ELEMENTS';
80const HOLEY_DOUBLE_ELEMENTS: constexpr ElementsKind generates
81'HOLEY_DOUBLE_ELEMENTS';
82const DICTIONARY_ELEMENTS: constexpr ElementsKind generates
83'DICTIONARY_ELEMENTS';
84
85const UINT8_ELEMENTS: constexpr ElementsKind generates 'UINT8_ELEMENTS';
86const INT8_ELEMENTS: constexpr ElementsKind generates 'INT8_ELEMENTS';
87const UINT16_ELEMENTS: constexpr ElementsKind generates 'UINT16_ELEMENTS';
88const INT16_ELEMENTS: constexpr ElementsKind generates 'INT16_ELEMENTS';
89const UINT32_ELEMENTS: constexpr ElementsKind generates 'UINT32_ELEMENTS';
90const INT32_ELEMENTS: constexpr ElementsKind generates 'INT32_ELEMENTS';
91const FLOAT32_ELEMENTS: constexpr ElementsKind generates 'FLOAT32_ELEMENTS';
92const FLOAT64_ELEMENTS: constexpr ElementsKind generates 'FLOAT64_ELEMENTS';
93const UINT8_CLAMPED_ELEMENTS: constexpr ElementsKind generates
94'UINT8_CLAMPED_ELEMENTS';
95const BIGUINT64_ELEMENTS: constexpr ElementsKind generates 'BIGUINT64_ELEMENTS';
96const BIGINT64_ELEMENTS: constexpr ElementsKind generates 'BIGINT64_ELEMENTS';
97
98type FixedUint8Array extends FixedTypedArray;
99type FixedInt8Array extends FixedTypedArray;
100type FixedUint16Array extends FixedTypedArray;
101type FixedInt16Array extends FixedTypedArray;
102type FixedUint32Array extends FixedTypedArray;
103type FixedInt32Array extends FixedTypedArray;
104type FixedFloat32Array extends FixedTypedArray;
105type FixedFloat64Array extends FixedTypedArray;
106type FixedUint8ClampedArray extends FixedTypedArray;
107type FixedBigUint64Array extends FixedTypedArray;
108type FixedBigInt64Array extends FixedTypedArray;
109
110const kAllFixedArrays: constexpr ExtractFixedArrayFlags generates
111'ExtractFixedArrayFlag::kAllFixedArrays';
112const kFixedArrays: constexpr ExtractFixedArrayFlags generates
113'ExtractFixedArrayFlag::kFixedArrays';
114
115const kFixedCOWArrayMapRootIndex: constexpr RootListIndex generates
116'Heap::kFixedCOWArrayMapRootIndex';
117const kEmptyFixedArrayRootIndex: constexpr RootListIndex generates
118'Heap::kEmptyFixedArrayRootIndex';
119
120const kInvalidArrayLength: constexpr MessageTemplate generates
121'MessageTemplate::kInvalidArrayLength';
122const kCalledNonCallable: constexpr MessageTemplate generates
123'MessageTemplate::kCalledNonCallable';
124const kCalledOnNullOrUndefined: constexpr MessageTemplate generates
125'MessageTemplate::kCalledOnNullOrUndefined';
126
127const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger';
128
129const kTruncateMinusZero: constexpr ToIntegerTruncationMode generates
130'ToIntegerTruncationMode::kTruncateMinusZero';
131
132const kNotTypedArray: constexpr MessageTemplate generates
133'MessageTemplate::kNotTypedArray';
134const kDetachedOperation: constexpr MessageTemplate generates
135'MessageTemplate::kDetachedOperation';
136const kBadSortComparisonFunction: constexpr MessageTemplate generates
137'MessageTemplate::kBadSortComparisonFunction';
138const kIncompatibleMethodReceiver: constexpr MessageTemplate generates
139'MessageTemplate::kIncompatibleMethodReceiver';
140const kInvalidDataViewAccessorOffset: constexpr MessageTemplate generates
141'MessageTemplate::kInvalidDataViewAccessorOffset';
142const kStrictReadOnlyProperty: constexpr MessageTemplate generates
143'MessageTemplate::kStrictReadOnlyProperty';
144
145extern macro TheHoleConstant(): Oddball;
146extern macro NullConstant(): Oddball;
147extern macro UndefinedConstant(): Oddball;
148extern macro TrueConstant(): Boolean;
149extern macro FalseConstant(): Boolean;
150extern macro Int32TrueConstant(): bool;
151extern macro Int32FalseConstant(): bool;
152
153const Hole: Oddball = TheHoleConstant();
154const Null: Oddball = NullConstant();
155const Undefined: Oddball = UndefinedConstant();
156const True: Boolean = TrueConstant();
157const False: Boolean = FalseConstant();
158
159const true: constexpr bool generates 'true';
160const false: constexpr bool generates 'false';
161
162const kStrict: constexpr LanguageMode generates 'LanguageMode::kStrict';
163const kSloppy: constexpr LanguageMode generates 'LanguageMode::kSloppy';
164
165const SMI_PARAMETERS: constexpr ParameterMode generates 'SMI_PARAMETERS';
166const INTPTR_PARAMETERS: constexpr ParameterMode generates 'INTPTR_PARAMETERS';
167
168
169const SKIP_WRITE_BARRIER: constexpr WriteBarrierMode
170    generates 'SKIP_WRITE_BARRIER';
171
172extern macro Is64(): constexpr bool;
173
174extern macro SelectBooleanConstant(bool): Boolean;
175
176extern macro Print(constexpr string);
177extern macro Print(constexpr string, Object);
178extern macro Print(Object);
179extern macro DebugBreak();
180extern macro ToInteger_Inline(Context, Object): Number;
181extern macro ToInteger_Inline(
182    Context, Object, constexpr ToIntegerTruncationMode): Number;
183extern macro ToLength_Inline(Context, Object): Number;
184extern macro ToNumber_Inline(Context, Object): Number;
185extern macro ToString_Inline(Context, Object): String;
186extern macro GetProperty(Context, Object, Object): Object;
187extern builtin SetProperty(Context, Object, Object, Object);
188extern builtin DeleteProperty(Context, Object, Object, LanguageMode);
189extern builtin HasProperty(Context, JSReceiver, Object): Boolean;
190
191extern macro ThrowRangeError(Context, constexpr MessageTemplate): never;
192extern macro ThrowTypeError(Context, constexpr MessageTemplate): never;
193extern macro ThrowTypeError(Context, constexpr MessageTemplate, Object): never;
194extern macro ThrowTypeError(
195    Context, constexpr MessageTemplate, Object, Object, Object): never;
196extern macro ArraySpeciesCreate(Context, Object, Number): Object;
197extern macro EnsureArrayPushable(Map): ElementsKind labels Bailout;
198
199extern builtin ToObject(Context, Object): JSReceiver;
200extern macro ToObject_Inline(Context, Object): JSReceiver;
201extern macro IsNullOrUndefined(Object): bool;
202extern macro IsTheHole(Object): bool;
203extern macro IsString(HeapObject): bool;
204extern builtin ToString(Context, Object): String;
205
206extern runtime CreateDataProperty(Context, Object, Object, Object);
207
208extern macro LoadRoot(constexpr RootListIndex): Object;
209extern macro StoreRoot(constexpr RootListIndex, Object): Object;
210extern macro LoadAndUntagToWord32Root(constexpr RootListIndex): int32;
211
212extern runtime StringEqual(Context, String, String): Oddball;
213extern builtin StringLessThan(Context, String, String): Boolean;
214
215extern macro StrictEqual(Object, Object): Boolean;
216extern runtime SmiLexicographicCompare(Context, Object, Object): Number;
217
218extern operator '<' macro Int32LessThan(int32, int32): bool;
219extern operator '>' macro Int32GreaterThan(int32, int32): bool;
220extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bool;
221extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bool;
222
223extern operator '==' macro SmiEqual(Smi, Smi): bool;
224extern operator '!=' macro SmiNotEqual(Smi, Smi): bool;
225extern operator '<' macro SmiLessThan(Smi, Smi): bool;
226extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bool;
227extern operator '>' macro SmiGreaterThan(Smi, Smi): bool;
228extern operator '>=' macro SmiGreaterThanOrEqual(Smi, Smi): bool;
229
230extern operator '==' macro ElementsKindEqual(
231    constexpr ElementsKind, constexpr ElementsKind): constexpr bool;
232extern operator '==' macro ElementsKindEqual(ElementsKind, ElementsKind): bool;
233extern macro IsFastElementsKind(constexpr ElementsKind): constexpr bool;
234extern macro IsDoubleElementsKind(constexpr ElementsKind): constexpr bool;
235
236extern macro SmiAbove(Smi, Smi): bool;
237
238extern operator '==' macro WordEqual(intptr, intptr): bool;
239extern operator '==' macro WordEqual(uintptr, uintptr): bool;
240extern operator '!=' macro WordNotEqual(intptr, intptr): bool;
241extern operator '!=' macro WordNotEqual(uintptr, uintptr): bool;
242extern operator '<' macro IntPtrLessThan(intptr, intptr): bool;
243extern operator '>' macro IntPtrGreaterThan(intptr, intptr): bool;
244extern operator '<=' macro IntPtrLessThanOrEqual(intptr, intptr): bool;
245extern operator '>=' macro IntPtrGreaterThanOrEqual(intptr, intptr): bool;
246extern operator '>=' macro UintPtrGreaterThanOrEqual(uintptr, uintptr): bool;
247
248extern operator '==' macro Float64Equal(float64, float64): bool;
249extern operator '!=' macro Float64NotEqual(float64, float64): bool;
250
251extern operator
252'<' macro BranchIfNumberLessThan(Number, Number): never labels Taken, NotTaken;
253extern operator
254'<=' macro BranchIfNumberLessThanOrEqual(Number, Number): never labels Taken,
255    NotTaken;
256extern operator
257'>' macro BranchIfNumberGreaterThan(Number, Number): never labels Taken,
258    NotTaken;
259extern operator '>=' macro BranchIfNumberGreaterThanOrEqual(Number, Number):
260    never labels Taken,
261    NotTaken;
262
263extern operator '==' macro WordEqual(Object, Object): bool;
264extern operator '!=' macro WordNotEqual(Object, Object): bool;
265
266extern operator '+' macro SmiAdd(Smi, Smi): Smi;
267extern operator '-' macro SmiSub(Smi, Smi): Smi;
268extern operator '&' macro SmiAnd(Smi, Smi): Smi;
269extern operator '|' macro SmiOr(Smi, Smi): Smi;
270extern operator '>>>' macro SmiShr(Smi, constexpr int31): Smi;
271extern operator '<<' macro SmiShl(Smi, constexpr int31): Smi;
272
273extern operator '+' macro IntPtrAdd(intptr, intptr): intptr;
274extern operator '-' macro IntPtrSub(intptr, intptr): intptr;
275extern operator '>>>' macro WordShr(uintptr, uintptr): uintptr;
276extern operator '<<' macro WordShl(intptr, intptr): intptr;
277extern operator '&' macro WordAnd(intptr, intptr): intptr;
278extern operator '&' macro WordAnd(uintptr, uintptr): uintptr;
279
280extern operator '+' macro Int32Add(int32, int32): int32;
281extern operator '-' macro Int32Sub(int32, int32): int32;
282extern operator '*' macro Int32Mul(int32, int32): int32;
283extern operator '%' macro Int32Mod(int32, int32): int32;
284extern operator '&' macro Word32And(int32, int32): int32;
285extern operator '&' macro Word32And(uint32, uint32): uint32;
286extern operator '==' macro
287ConstexprInt31Equal(constexpr int31, constexpr int31): constexpr bool;
288
289extern operator '==' macro Word32Equal(int32, int32): bool;
290extern operator '==' macro Word32Equal(uint32, uint32): bool;
291extern operator '!=' macro Word32NotEqual(int32, int32): bool;
292extern operator '!=' macro Word32NotEqual(uint32, uint32): bool;
293extern operator '>>>' macro Word32Shr(uint32, uint32): uint32;
294extern operator '<<' macro Word32Shl(int32, int32): int32;
295extern operator '<<' macro Word32Shl(uint32, uint32): uint32;
296extern operator '|' macro Word32Or(int32, int32): int32;
297extern operator '|' macro Word32Or(uint32, uint32): uint32;
298
299extern operator '+' macro NumberAdd(Number, Number): Number;
300extern operator '-' macro NumberSub(Number, Number): Number;
301extern macro NumberMin(Number, Number): Number;
302extern macro NumberMax(Number, Number): Number;
303macro min(x: Number, y: Number): Number {
304  return NumberMin(x, y);
305}
306macro max(x: Number, y: Number): Number {
307  return NumberMax(x, y);
308}
309
310extern macro SmiMax(Smi, Smi): Smi;
311extern macro SmiMin(Smi, Smi): Smi;
312
313extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool;
314extern operator '!' macro Word32BinaryNot(bool): bool;
315extern operator '!' macro IsFalse(Boolean): bool;
316
317extern operator '.map' macro LoadMap(HeapObject): Map;
318extern operator '.map=' macro StoreMap(HeapObject, Map);
319extern operator
320'.instanceType' macro LoadInstanceType(HeapObject): InstanceType;
321
322extern operator '.length' macro LoadStringLengthAsWord(String): intptr;
323
324extern operator '.length' macro GetArgumentsLength(constexpr Arguments): intptr;
325extern operator
326'[]' macro GetArgumentValue(constexpr Arguments, intptr): Object;
327
328extern operator 'is<Smi>' macro TaggedIsSmi(Object): bool;
329extern operator 'isnt<Smi>' macro TaggedIsNotSmi(Object): bool;
330extern macro TaggedIsPositiveSmi(Object): bool;
331
332extern macro HeapObjectToJSDataView(HeapObject): JSDataView labels CastError;
333extern macro TaggedToHeapObject(Object): HeapObject labels CastError;
334extern macro TaggedToSmi(Object): Smi labels CastError;
335extern macro HeapObjectToJSArray(HeapObject): JSArray labels CastError;
336extern macro HeapObjectToCallable(HeapObject): Callable labels CastError;
337extern macro HeapObjectToFixedArray(HeapObject):
338    FixedArray labels CastError;
339extern macro HeapObjectToFixedDoubleArray(HeapObject):
340    FixedDoubleArray labels CastError;
341extern macro TaggedToNumber(Object): Number labels CastError;
342
343macro cast_HeapObject<A : type>(o : HeapObject) : A labels CastError;
344cast_HeapObject<HeapObject>(o : HeapObject) : HeapObject labels CastError { return o; }
345cast_HeapObject<FixedArray>(o: HeapObject): FixedArray labels CastError {
346  return HeapObjectToFixedArray(o) otherwise CastError;
347}
348cast_HeapObject<FixedDoubleArray>(o: HeapObject): FixedDoubleArray labels CastError {
349  return HeapObjectToFixedDoubleArray(o) otherwise CastError;
350}
351cast_HeapObject<JSDataView>(o: HeapObject): JSDataView labels CastError {
352  return HeapObjectToJSDataView(o) otherwise CastError;
353}
354cast_HeapObject<Callable>(o: HeapObject): Callable labels CastError {
355  return HeapObjectToCallable(o) otherwise CastError;
356}
357cast_HeapObject<JSArray>(o: HeapObject): JSArray labels CastError {
358  return HeapObjectToJSArray(o) otherwise CastError;
359}
360
361macro cast<A : type>(o: HeapObject): A labels CastError {
362  return cast_HeapObject<A>(o) otherwise CastError;
363}
364
365// cast_HeapObject allows this default-implementation to be non-recursive.
366// Otherwise the generated CSA code might run into infinite recursion.
367macro cast<A : type>(o: Object): A labels CastError {
368  return cast_HeapObject<A>(
369    TaggedToHeapObject(o) otherwise CastError) otherwise CastError;
370}
371cast<Smi>(o: Object): Smi labels CastError {
372  return TaggedToSmi(o) otherwise CastError;
373}
374cast<Number>(o: Object): Number labels CastError {
375  return TaggedToNumber(o) otherwise CastError;
376}
377
378extern macro AllocateHeapNumberWithValue(float64): HeapNumber;
379extern macro ChangeInt32ToTagged(int32): Number;
380extern macro ChangeUint32ToTagged(uint32): Number;
381extern macro Unsigned(int32): uint32;
382extern macro Unsigned(intptr): uintptr;
383extern macro Unsigned(RawPtr): uintptr;
384extern macro Signed(uint32): int32;
385extern macro Signed(uintptr): intptr;
386extern macro Signed(RawPtr): intptr;
387extern macro TruncateIntPtrToInt32(intptr): int32;
388extern macro SmiTag(intptr): Smi;
389extern macro SmiFromInt32(int32): Smi;
390extern macro SmiUntag(Smi): intptr;
391extern macro SmiToInt32(Smi): int32;
392extern macro RoundIntPtrToFloat64(intptr): float64;
393extern macro LoadHeapNumberValue(HeapNumber): float64;
394extern macro ChangeFloat32ToFloat64(float32): float64;
395extern macro ChangeNumberToFloat64(Number): float64;
396extern macro ChangeFloat64ToUintPtr(float64): uintptr;
397extern macro ChangeInt32ToIntPtr(int32): intptr;   // Sign-extends.
398extern macro ChangeUint32ToWord(uint32): uintptr;  // Doesn't sign-extend.
399
400extern macro NumberConstant(constexpr float64): Number;
401extern macro NumberConstant(constexpr int32): Number;
402extern macro IntPtrConstant(constexpr int31): intptr;
403extern macro IntPtrConstant(constexpr int32): intptr;
404extern macro Int32Constant(constexpr int31): int31;
405extern macro Int32Constant(constexpr int32): int32;
406extern macro Float64Constant(constexpr int31): float64;
407extern macro SmiConstant(constexpr int31): Smi;
408extern macro BoolConstant(constexpr bool): bool;
409extern macro StringConstant(constexpr string): String;
410extern macro LanguageModeConstant(constexpr LanguageMode): LanguageMode;
411extern macro Int32Constant(constexpr ElementsKind): ElementsKind;
412
413macro from_constexpr<A : type>(o: constexpr int31): A;
414from_constexpr<intptr>(i: constexpr int31): intptr {
415  return IntPtrConstant(i);
416}
417from_constexpr<int31>(i: constexpr int31): int31 {
418  return Int32Constant(i);
419}
420from_constexpr<int32>(i: constexpr int31): int32 {
421  return Int32Constant(i);
422}
423from_constexpr<uint32>(i: constexpr int31): uint32 {
424  return Unsigned(Int32Constant(i));
425}
426from_constexpr<uintptr>(i: constexpr int31): uintptr {
427  return ChangeUint32ToWord(i);
428}
429from_constexpr<Smi>(i: constexpr int31): Smi {
430  return SmiConstant(i);
431}
432from_constexpr<Number>(i: constexpr int31): Number {
433  return SmiConstant(i);
434}
435from_constexpr<float64>(i: constexpr int31): float64 {
436  return Float64Constant(i);
437}
438macro from_constexpr<A : type>(o: constexpr int32): A;
439from_constexpr<intptr>(i: constexpr int32): intptr {
440  return IntPtrConstant(i);
441}
442from_constexpr<int32>(i: constexpr int32): int32 {
443  return Int32Constant(i);
444}
445from_constexpr<Number>(i: constexpr int32): Number {
446  return NumberConstant(i);
447}
448macro from_constexpr<A : type>(o: constexpr float64): A;
449from_constexpr<Number>(f: constexpr float64): Number {
450  return NumberConstant(f);
451}
452macro from_constexpr<A : type>(b: constexpr bool): A;
453from_constexpr<bool>(b: constexpr bool): bool {
454  return BoolConstant(b);
455}
456macro from_constexpr<A : type>(l: constexpr LanguageMode): A;
457from_constexpr<LanguageMode>(b: constexpr LanguageMode): LanguageMode {
458  return LanguageModeConstant(b);
459}
460macro from_constexpr<A : type>(e: constexpr ElementsKind): A;
461from_constexpr<ElementsKind>(e: constexpr ElementsKind): ElementsKind {
462  return Int32Constant(e);
463}
464macro from_constexpr<A : type>(s: constexpr string): A;
465from_constexpr<String>(s: constexpr string): String {
466  return StringConstant(s);
467}
468from_constexpr<Object>(s: constexpr string): Object {
469  return StringConstant(s);
470}
471
472macro convert<A : type>(i: constexpr int31): A {
473  return i;
474}
475macro convert<A : type>(i: int32): A;
476convert<Number>(i: int32): Number {
477  return ChangeInt32ToTagged(i);
478}
479convert<intptr>(i: int32): intptr {
480  return ChangeInt32ToIntPtr(i);
481}
482convert<Smi>(i: int32): Smi {
483  return SmiFromInt32(i);
484}
485macro convert<A : type>(ui: uint32): A;
486convert<Number>(ui: uint32): Number {
487  return ChangeUint32ToTagged(ui);
488}
489convert<Smi>(ui: uint32): Smi {
490  return SmiFromInt32(Signed(ui));
491}
492convert<uintptr>(ui: uint32): uintptr {
493  return ChangeUint32ToWord(ui);
494}
495macro convert<A : type>(i: intptr): A;
496convert<int32>(i: intptr): int32 {
497  return TruncateIntPtrToInt32(i);
498}
499convert<Smi>(i: intptr): Smi {
500  return SmiTag(i);
501}
502macro convert<A : type>(ui: uintptr): A;
503convert<uint32>(ui: uintptr): uint32 {
504  return Unsigned(TruncateIntPtrToInt32(Signed(ui)));
505}
506macro convert<A : type>(s: Smi): A;
507convert<intptr>(s: Smi): intptr {
508  return SmiUntag(s);
509}
510convert<int32>(s: Smi): int32 {
511  return SmiToInt32(s);
512}
513macro convert<A : type>(h: HeapNumber): A;
514convert<float64>(h: HeapNumber): float64 {
515  return LoadHeapNumberValue(h);
516}
517macro convert<A : type>(n: Number): A;
518convert<float64>(n: Number): float64 {
519  return ChangeNumberToFloat64(n);
520}
521macro convert<A : type>(f: float32): A;
522convert<float64>(f: float32): float64 {
523  return ChangeFloat32ToFloat64(f);
524}
525macro convert<A : type>(d: float64): A;
526convert<Number>(d: float64): Number {
527  return AllocateHeapNumberWithValue(d);
528}
529convert<uintptr>(d: float64): uintptr {
530  return ChangeFloat64ToUintPtr(d);
531}
532macro convert<A : type>(r: RawPtr): A;
533convert<uintptr>(r: RawPtr): uintptr {
534  return Unsigned(r);
535}
536convert<intptr>(r: RawPtr): intptr {
537  return Signed(r);
538}
539
540extern macro UnsafeCastNumberToHeapNumber(Number): HeapNumber;
541extern macro UnsafeCastObjectToFixedArrayBase(Object): FixedArrayBase;
542extern macro UnsafeCastObjectToFixedArray(Object): FixedArray;
543extern macro UnsafeCastObjectToFixedDoubleArray(Object): FixedDoubleArray;
544extern macro UnsafeCastObjectToHeapNumber(Object): HeapNumber;
545extern macro UnsafeCastObjectToCallable(Object): Callable;
546extern macro UnsafeCastObjectToSmi(Object): Smi;
547extern macro UnsafeCastObjectToNumber(Object): Number;
548extern macro UnsafeCastObjectToHeapObject(Object): HeapObject;
549extern macro UnsafeCastObjectToJSArray(Object): JSArray;
550extern macro UnsafeCastObjectToFixedTypedArrayBase(Object): FixedTypedArrayBase;
551extern macro UnsafeCastObjectToNumberDictionary(Object): NumberDictionary;
552extern macro UnsafeCastObjectToJSReceiver(Object): JSReceiver;
553extern macro UnsafeCastObjectToJSObject(Object): JSObject;
554extern macro UnsafeCastObjectToMap(Object): Map;
555
556macro unsafe_cast<A : type>(n: Number): A;
557unsafe_cast<HeapNumber>(n: Number): HeapNumber {
558  return UnsafeCastNumberToHeapNumber(n);
559}
560macro unsafe_cast<A : type>(o: Object): A;
561unsafe_cast<FixedArray>(o: Object): FixedArray {
562  return UnsafeCastObjectToFixedArray(o);
563}
564unsafe_cast<FixedDoubleArray>(o: Object): FixedDoubleArray {
565  return UnsafeCastObjectToFixedDoubleArray(o);
566}
567unsafe_cast<HeapNumber>(o: Object): HeapNumber {
568  return UnsafeCastObjectToHeapNumber(o);
569}
570unsafe_cast<Callable>(o: Object): Callable {
571  return UnsafeCastObjectToCallable(o);
572}
573unsafe_cast<Smi>(o: Object): Smi {
574  return UnsafeCastObjectToSmi(o);
575}
576unsafe_cast<Number>(o: Object): Number {
577  return UnsafeCastObjectToNumber(o);
578}
579unsafe_cast<HeapObject>(o: Object): HeapObject {
580  return UnsafeCastObjectToHeapObject(o);
581}
582unsafe_cast<JSArray>(o: Object): JSArray {
583  return UnsafeCastObjectToJSArray(o);
584}
585unsafe_cast<FixedTypedArrayBase>(o: Object): FixedTypedArrayBase {
586  return UnsafeCastObjectToFixedTypedArrayBase(o);
587}
588unsafe_cast<NumberDictionary>(o: Object): NumberDictionary {
589  return UnsafeCastObjectToNumberDictionary(o);
590}
591unsafe_cast<JSReceiver>(o: Object): JSReceiver {
592  return UnsafeCastObjectToJSReceiver(o);
593}
594unsafe_cast<JSObject>(o: Object): JSObject {
595  return UnsafeCastObjectToJSObject(o);
596}
597unsafe_cast<Map>(o: Object): Map {
598  return UnsafeCastObjectToMap(o);
599}
600unsafe_cast<FixedArrayBase>(o: Object): FixedArrayBase {
601  return UnsafeCastObjectToFixedArrayBase(o);
602}
603
604const kCOWMap: Map = unsafe_cast<Map>(LoadRoot(kFixedCOWArrayMapRootIndex));
605const kEmptyFixedArray: FixedArrayBase =
606    unsafe_cast<FixedArrayBase>(LoadRoot(kEmptyFixedArrayRootIndex));
607
608extern macro BranchIfFastJSArray(Object, Context): never labels Taken, NotTaken;
609extern macro BranchIfNotFastJSArray(Object, Context): never labels Taken,
610    NotTaken;
611
612extern macro IsPrototypeInitialArrayPrototype(Context, Map): bool;
613extern macro IsNoElementsProtectorCellInvalid(): bool;
614extern macro IsArraySpeciesProtectorCellInvalid(): bool;
615extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool;
616extern macro IsPromiseSpeciesProtectorCellInvalid(): bool;
617
618extern operator
619'.buffer' macro LoadTypedArrayBuffer(JSTypedArray): JSArrayBuffer;
620
621extern operator '.data_ptr' macro LoadDataPtr(JSTypedArray): RawPtr;
622
623extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind;
624extern operator
625'.elements_kind' macro LoadElementsKind(JSTypedArray): ElementsKind;
626
627extern operator '.elements' macro LoadElements(JSObject): FixedArrayBase;
628extern operator '.elements=' macro StoreElements(JSObject, FixedArrayBase);
629
630extern operator '.length' macro LoadTypedArrayLength(JSTypedArray): Smi;
631extern operator '.length' macro LoadJSArrayLength(JSArray): Number;
632extern operator '.length_fast' macro LoadFastJSArrayLength(JSArray): Smi;
633extern operator '.length=' macro StoreJSArrayLength(JSArray, Smi);
634
635extern operator '.length' macro LoadFixedArrayBaseLength(FixedArrayBase): Smi;
636extern operator '[]' macro LoadFixedArrayElement(FixedArray, intptr): Object;
637extern operator '[]' macro LoadFixedArrayElement(FixedArray, Smi): Object;
638extern operator
639'[]' macro LoadFixedArrayElement(FixedArray, constexpr int31): Object;
640extern operator
641'[]=' macro StoreFixedArrayElement(FixedArray, intptr, Object): void;
642extern operator
643'[]=' macro StoreFixedArrayElement(
644    FixedArray, constexpr int31, Object): void;
645extern operator
646'[]=' macro StoreFixedArrayElementSmi(FixedArray, Smi, Object): void;
647
648extern macro StoreFixedArrayElementSmi(FixedArray, Smi, Object,
649  constexpr WriteBarrierMode): void;
650
651extern operator '.instance_type' macro LoadMapInstanceType(Map): int32;
652
653extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64;
654extern macro Float64SilenceNaN(float64): float64;
655
656extern macro StoreFixedDoubleArrayElement(
657    FixedDoubleArray, Object, float64, constexpr ParameterMode);
658macro StoreFixedDoubleArrayElementWithSmiIndex(
659    array: FixedDoubleArray, index: Smi, value: float64) {
660  StoreFixedDoubleArrayElement(array, index, value, SMI_PARAMETERS);
661}
662
663extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr):
664    Object labels NotData,
665    IfHole;
666extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, Object)
667labels NotData, IfHole, ReadOnly;
668
669extern macro IsFastElementsKind(ElementsKind): bool;
670extern macro IsDoubleElementsKind(ElementsKind): bool;
671extern macro IsFastSmiOrTaggedElementsKind(ElementsKind): bool;
672extern macro IsFastSmiElementsKind(ElementsKind): bool;
673extern macro IsHoleyFastElementsKind(ElementsKind): bool;
674
675extern macro AllocateZeroedFixedArray(intptr): FixedArray;
676extern macro AllocateZeroedFixedDoubleArray(intptr): FixedDoubleArray;
677
678extern macro CopyFixedArrayElements(
679    constexpr ElementsKind, FixedArray, constexpr ElementsKind, FixedArray,
680    intptr, intptr, intptr): void;
681extern macro CopyFixedArrayElements(
682    constexpr ElementsKind, FixedArray, constexpr ElementsKind, FixedArray, Smi,
683    Smi, Smi): void;
684
685extern macro AllocateJSArray(constexpr ElementsKind, Map, intptr, Smi): JSArray;
686extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray;
687extern macro IsElementsKindGreaterThan(
688    ElementsKind, constexpr ElementsKind): bool;
689
690extern macro LoadDoubleWithHoleCheck(FixedDoubleArray, Smi): float64
691labels IfHole;
692
693extern macro Call(Context, Callable, Object): Object;
694extern macro Call(Context, Callable, Object, Object): Object;
695extern macro Call(Context, Callable, Object, Object, Object): Object;
696extern macro Call(Context, Callable, Object, Object, Object, Object): Object;
697extern macro Call(
698    Context, Callable, Object, Object, Object, Object, Object): Object;
699extern macro Call(
700    Context, Callable, Object, Object, Object, Object, Object, Object): Object;
701
702extern macro ExtractFixedArray(
703    FixedArray, Smi, Smi, Smi, constexpr ExtractFixedArrayFlags): FixedArray;
704
705extern builtin ExtractFastJSArray(Context, JSArray, Smi, Smi): JSArray;
706
707macro LoadElementNoHole<T : type>(a: JSArray, index: Smi): Object labels IfHole;
708
709LoadElementNoHole<FixedArray>(a: JSArray, index: Smi): Object
710labels IfHole {
711  try {
712    let elements: FixedArray =
713        cast<FixedArray>(a.elements) otherwise Unexpected;
714    let e: Object = elements[index];
715    if (e == Hole) {
716      goto IfHole;
717    }
718    return e;
719  }
720  label Unexpected {
721    unreachable;
722  }
723}
724
725LoadElementNoHole<FixedDoubleArray>(a: JSArray, index: Smi): Object
726labels IfHole {
727  try {
728    let elements: FixedDoubleArray =
729        cast<FixedDoubleArray>(a.elements) otherwise Unexpected;
730    let e: float64 = LoadDoubleWithHoleCheck(elements, index) otherwise IfHole;
731    return AllocateHeapNumberWithValue(e);
732  }
733  label Unexpected {
734    unreachable;
735  }
736}
737
738extern macro IsCallable(HeapObject): bool;
739extern macro IsJSArray(HeapObject): bool;
740extern macro TaggedIsCallable(Object): bool;
741extern macro IsDetachedBuffer(JSArrayBuffer): bool;
742extern macro IsHeapNumber(HeapObject): bool;
743extern macro IsFixedArray(HeapObject): bool;
744extern macro IsExtensibleMap(Map): bool;
745extern macro IsCustomElementsReceiverInstanceType(int32): bool;
746extern macro Typeof(Object): Object;
747
748// Return true iff number is NaN.
749macro NumberIsNaN(number: Number): bool {
750  typeswitch(number) {
751    case (Smi) {
752      return false;
753    } case (hn : HeapNumber) {
754      let value: float64 = convert<float64>(hn);
755      return value != value;
756    }
757  }
758}
759
760extern macro BranchIfToBooleanIsTrue(Object): never labels Taken, NotTaken;
761
762macro ToBoolean(obj: Object): bool {
763  if (BranchIfToBooleanIsTrue(obj)) {
764    return true;
765  } else {
766    return false;
767  }
768}
769
770macro ToIndex(input: Object, context: Context): Number labels RangeError {
771  if (input == Undefined) {
772    return 0;
773  }
774
775  let value: Number = ToInteger_Inline(context, input, kTruncateMinusZero);
776  if (value < 0 || value > kMaxSafeInteger) {
777    goto RangeError;
778  }
779
780  return value;
781}
782