• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16declare interface ArkTools {
17  isAOTCompiled(args: any): boolean
18}
19
20//int array
21let literalIntArrayWithHole = [0, , 2, , 4, ,]
22let nIntArray = new Array(6)
23nIntArray[0] = 0
24nIntArray[2] = 2
25nIntArray[4] = 4
26function returnDoubleTypeIntNotConstant (x) {
27  if (x > 0) {
28    return 3.5 + 0.5
29  } else {
30    return 1.5 + 0.5
31  }
32}
33//double array
34let literalDoubleArrayWithHole = [0.5, , 2.5, , 4.5, ,]
35function returnNotConstantDouble (x) {
36  if (x > 0) {
37    return 4 + 0.5
38  } else {
39    return 2 + 0.5
40  }
41}
42let nDoubleArray = new Array(5)
43nDoubleArray[1] = 1.5
44nDoubleArray[4] = 4.5
45//string array
46let literalStringArrayWithHole = ['string1', , 'string2', , 'string4', ,]
47let nStringArray = new Array(5)
48nStringArray[1] = '1'
49nStringArray[4] = '4'
50function returnNotLitaralString (x) {
51  if (x > 0) {
52    return 'string' + '4'
53  } else {
54    return 'string4'
55  }
56}
57//object array
58let find1 = { 1: 1 }
59class findClass {
60  x
61  constructor (x) {
62    this.x = x
63  }
64}
65let find3 = new findClass(3)
66let find5 = new Date()
67let objArrayWithHoleNeverFind = [{ 0: 0 }, , { 2: 2 }, , { 4: 4 }, ,]
68let objnewArraywithHoleNeverFind = new Array(7)
69objnewArraywithHoleNeverFind[0] = { 0: 0 }
70objnewArraywithHoleNeverFind[2] = { 2: 2 }
71objnewArraywithHoleNeverFind[4] = { 4: 4 }
72
73let objArrayWithHoleCanFind = [, find1, , find3, , find5]
74let objnewArraywithHoleCanFind = new Array(7)
75objnewArraywithHoleCanFind[1] = find1
76objnewArraywithHoleCanFind[3] = find3
77objnewArraywithHoleCanFind[5] = find5
78
79//====================start nomarl kind test=================//
80//lastIndexOf int
81print('---- Case group #1: int[] ----') //: ---- Case group #1: int[] ----
82//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
83print('case 1.1: ', literalIntArrayWithHole.lastIndexOf(4)) //: case 1.1:  4
84//aot: [trace] aot inline function name: #*#returnDoubleTypeIntNotConstant@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
85//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
86print(
87  'case 1.2: ',
88  literalIntArrayWithHole.lastIndexOf(returnDoubleTypeIntNotConstant(1))
89) //: case 1.2:  4
90//aot: [trace] aot inline function name: #*#returnDoubleTypeIntNotConstant@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
91//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
92print(
93  'case 1.3: ',
94  literalIntArrayWithHole.lastIndexOf(returnDoubleTypeIntNotConstant(0))
95) //: case 1.3:  2
96//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
97print('case 1.4: ', nIntArray.lastIndexOf(4)) //: case 1.4:  4
98//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
99print('case 1.5: ', literalIntArrayWithHole.lastIndexOf(undefined)) //: case 1.5:  -1
100//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
101print('case 1.6: ', nIntArray.lastIndexOf(nIntArray.length)) //: case 1.6:  -1
102
103//lastIndexOf double
104print('---- Case group #2: double[] ----') //: ---- Case group #2: double[] ----
105//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
106print('case 2.1: ', literalDoubleArrayWithHole.lastIndexOf(4.5)) //: case 2.1:  4
107//aot: [trace] aot inline function name: #*#returnNotConstantDouble@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
108//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
109print(
110  'case 2.2: ',
111  literalDoubleArrayWithHole.lastIndexOf(returnNotConstantDouble(1))
112) //: case 2.2:  4
113//aot: [trace] aot inline function name: #*#returnNotConstantDouble@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
114//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
115print(
116  'case 2.3: ',
117  literalDoubleArrayWithHole.lastIndexOf(returnNotConstantDouble(0))
118) //: case 2.3:  2
119//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
120print('case 2.4: ', nDoubleArray.lastIndexOf(4.5)) //: case 2.4:  4
121//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
122print('case 2.5: ', literalDoubleArrayWithHole.lastIndexOf(undefined)) //: case 2.5:  -1
123
124//lastIndexOf string
125print('---- Case group #3: string[] ----') //: ---- Case group #3: string[] ----
126//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
127print('case 3.1: ', literalStringArrayWithHole.lastIndexOf('string4')) //: case 3.1:  4
128//aot: [trace] aot inline function name: #*#returnNotLitaralString@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
129//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
130print(
131  'case 3.2: ',
132  literalStringArrayWithHole.lastIndexOf(returnNotLitaralString(1))
133) //: case 3.2:  4
134//aot: [trace] aot inline function name: #*#returnNotLitaralString@builtinArrayLastIndexOf caller function name: func_main_0@builtinArrayLastIndexOf
135//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
136print(
137  'case 3.3: ',
138  literalStringArrayWithHole.lastIndexOf(returnNotLitaralString(0))
139) //: case 3.3:  4
140//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
141print('case 3.4: ', nStringArray.lastIndexOf('4')) //: case 3.4:  4
142//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
143print('case 3.5: ', nStringArray.lastIndexOf(undefined)) //: case 3.5:  -1
144
145//lastIndexOf obj
146print('---- Case group #4: object[] ----') //: ---- Case group #4: object[] ----
147//neverequal
148//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
149print('case 4.1: ', objArrayWithHoleNeverFind.lastIndexOf({ 4: 4 })) //: case 4.1:  -1
150//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
151print('case 4.2: ', objnewArraywithHoleNeverFind.lastIndexOf({ 4: 4 })) //: case 4.2:  -1
152//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
153print('case 4.3: ', objnewArraywithHoleNeverFind.lastIndexOf(undefined)) //: case 4.3:  -1
154//can find
155//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
156print('case 4.4: ', objArrayWithHoleCanFind.lastIndexOf(find1)) //: case 4.4:  1
157//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
158print('case 4.5: ', objArrayWithHoleCanFind.lastIndexOf(find3)) //: case 4.5:  3
159//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
160print('case 4.6: ', objArrayWithHoleCanFind.lastIndexOf(find5)) //: case 4.6:  5
161//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
162print('case 4.7: ', objnewArraywithHoleCanFind.lastIndexOf(find1)) //: case 4.7:  1
163//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
164print('case 4.8: ', objnewArraywithHoleCanFind.lastIndexOf(find3)) //: case 4.8:  3
165//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
166print('case 4.9: ', objnewArraywithHoleCanFind.lastIndexOf(find5)) //: case 4.9:  5
167
168//============special test
169print('---- Case group #5: special array ----') //: ---- Case group #5: special array ----
170//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinArrayLastIndexOf
171let specialArray = [
172  null,
173  ,
174  false,
175  true,
176  undefined,
177  +0,
178  -0,
179  BigInt(123456),
180  NaN,
181  5,
182  5.5
183]
184//lastIndexOf use strict equal
185//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
186print('case 5.1: ', specialArray.lastIndexOf(NaN)) //: case 5.1:  -1
187//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
188print('case 5.2: ', specialArray.lastIndexOf(undefined, 3)) //: case 5.2:  -1
189//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
190print('case 5.3: ', specialArray.lastIndexOf(undefined)) //: case 5.3:  4
191//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
192print('case 5.4: ', specialArray.lastIndexOf(NaN)) //: case 5.4:  -1
193//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
194print('case 5.5: ', specialArray.lastIndexOf(+0)) //: case 5.5:  6
195//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
196print('case 5.6: ', specialArray.lastIndexOf(-0)) //: case 5.6:  6
197//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
198print('case 5.7: ', specialArray.lastIndexOf(false)) //: case 5.7:  2
199//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
200print('case 5.8: ', specialArray.lastIndexOf(true)) //: case 5.8:  3
201//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
202print('case 5.9: ', specialArray.lastIndexOf(null)) //: case 5.9:  0
203//aot: [trace] aot inline builtin: BigInt, caller function name:func_main_0@builtinArrayLastIndexOf
204//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
205print('case 5.10: ', specialArray.lastIndexOf(BigInt(123456))) //: case 5.10:  7
206//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
207print('case 5.11: ', specialArray.lastIndexOf(5)) //: case 5.11:  9
208//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
209print('case 5.12: ', specialArray.lastIndexOf(5.5)) //: case 5.12:  10
210
211print('---- Case group #6: unusual cases ----') //: ---- Case group #6: unusual cases ----
212//aot: [trace] aot call builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
213print('case 6.1: ', specialArray.lastIndexOf()) //: case 6.1:  4
214//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
215print(
216  'case 6.2: ',
217  specialArray.lastIndexOf(() => {})
218) //: case 6.2:  -1
219//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
220print('case 6.3: ', specialArray.lastIndexOf(true, 2000000)) //: case 6.3:  3
221//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
222print('case 6.4: ', specialArray.lastIndexOf(true, -2000000)) //: case 6.4:  -1
223//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
224print('case 6.5: ', specialArray.lastIndexOf(true, -1)) //: case 6.5:  3
225//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
226print('case 6.6: ', specialArray.lastIndexOf(5, 5, 78)) //: case 6.6:  -1
227
228print('---- Case group #7: not int index ----') //: ---- Case group #7: not int index ----
229function notIntIndex () {
230  let specialArray = [1, 2, NaN]
231  //aot: [trace] Check Type: IndexNotInt
232  print('case 7.1: ', specialArray.lastIndexOf(false, 'str'))
233}
234notIntIndex() //: case 7.1:  -1
235
236// Check inside try-block
237print('---- Case group #8: inside try-block ----') //: ---- Case group #8: inside try-block ----
238try {
239  //aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
240  print('case 8.1: ', specialArray.lastIndexOf(null)) //: case 8.1:  0
241} catch (e) {}
242
243print('---- Case group #9: target with valueOf ----') //: ---- Case group #9: target with valueOf ----
244let obj = {}
245obj.valueOf = () => {
246  return 5
247}
248//aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
249print('case 9.1: ', specialArray.lastIndexOf(obj)) //: case 9.1:  -1
250
251print('---- Case group #10: throwing ----') //: ---- Case group #10: throwing ----
252function Throwing () {
253  this.value = 2
254  Throwing.prototype.valueOf = function () {
255    if (this.value > 0) {
256      throw new Error('positive')
257    }
258    return this.value
259  }
260}
261let throwingObj = new Throwing()
262try {
263  //aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
264  print('case 10.1: ', specialArray.lastIndexOf(throwingObj)) //: case 10.1:  -1
265} catch (e) {
266  print(e)
267} finally {
268  //aot: [trace] aot inline builtin: Array.LastIndexOf, caller function name:func_main_0@builtinArrayLastIndexOf
269  print('case 10.2: ', specialArray.lastIndexOf(obj)) //: case 10.2:  -1
270}
271
272//===========deopt type
273print('---- Case group #11: de-opt ----') //: ---- Case group #11: de-opt ----
274//aot: [trace] Check Type: NotStableArray1
275function prototypeChange () {
276  let tArray = [1, , 3]
277  Array.prototype[1] = 2
278  print('case ProtoChange: ', tArray.lastIndexOf(2))
279}
280prototypeChange() //: case ProtoChange:  1
281
282//aot: [trace] Check Type: NotStableArray1
283function lengthChange () {
284  let tArray = [1, , 3]
285  tArray.length = 2
286  print('case LengthChange: ', tArray.lastIndexOf(3))
287}
288lengthChange() //: case LengthChange:  -1
289
290// Replace standard builtin
291function replace (a: any) {
292  return a
293}
294
295let newArr = [1, 2, NaN]
296let true_lastIndexOf = newArr.lastIndexOf
297newArr.lastIndexOf = replace
298
299print('case BuiltinFunctionChange: ', newArr.lastIndexOf(undefined)) //: case BuiltinFunctionChange:  undefined
300newArr.lastIndexOf = true_lastIndexOf
301//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
302print('case BuiltinHClassMismatch: ', newArr.lastIndexOf(undefined)) //: case BuiltinHClassMismatch:  -1
303
304function dolastIndexOf (x: any): any {
305  return newArr.lastIndexOf(x)
306}
307
308function printlastIndexOf (promptStr: string, x: any) {
309  try {
310    print(promptStr, dolastIndexOf(x))
311  } finally {
312  }
313}
314
315let promptStr = 'pgo: '
316if (ArkTools.isAOTCompiled(printlastIndexOf)) {
317  // Replace standard builtin after call to standard builtin was profiled
318  newArr.lastIndexOf = replace
319  promptStr = 'aot: '
320}
321printlastIndexOf(promptStr, 2) //pgo: pgo:  1
322//aot: [trace] Check Type: NotCallTarget1
323//aot: aot:  2
324
325printlastIndexOf(promptStr, 'abc') //pgo: pgo:  -1
326//aot: [trace] Check Type: NotCallTarget1
327//aot: aot:  abc
328
329newArr.lastIndexOf = true_lastIndexOf
330
331function lastIndexOfCase1 () {
332  print('case 1 lastIndexOf') //: case 1 lastIndexOf
333  let arr1 = [1, 2]
334  let arr2 = [1, 2]
335  arr2.garbage = function (x: any): any {
336    return undefined
337  }
338  //aot: [trace] Check Type: NotStableArray1
339  print('de-opt case 1.1: ', arr1.lastIndexOf(1)) //: de-opt case 1.1:  0
340  print('de-opt case 1.2: ', arr2.lastIndexOf(2)) //: de-opt case 1.2:  1
341}
342lastIndexOfCase1()
343
344function lastIndexOfCase2 () {
345  print('case 2 lastIndexOf') //: case 2 lastIndexOf
346  let arr1 = [1, 2]
347  let arr2 = [1, 2]
348  arr2.lastIndexOf = function (x: any) {
349    return x
350  }
351
352  //aot: [trace] aot inline builtin: Object.getPrototypeOf, caller function name:#*#lastIndexOfCase2@builtinArrayLastIndexOf
353  print(Object.getPrototypeOf(arr2) === Array.prototype) //: true
354
355  //aot: [trace] Check Type: NotStableArray1
356  print('de-opt case 2.1: ', arr1.lastIndexOf(1)) //: de-opt case 2.1:  0
357  print('de-opt case 2.2: ', arr2.lastIndexOf(1)) //: de-opt case 2.2:  1
358}
359lastIndexOfCase2()
360
361function lastIndexOfCase3 () {
362  print('case 3 lastIndexOf') //: case 3 lastIndexOf
363  let marr = [1, 2]
364  let true_lastIndexOf = marr.lastIndexOf
365  let mimicArray = {
366    lastIndexOf: true_lastIndexOf
367  }
368
369  //aot: [trace] Check Type: NotStableArray1
370  print('de-opt case 3.1: ', marr.lastIndexOf(500)) //: de-opt case 3.1:  -1
371  Object.setPrototypeOf(marr, mimicArray)
372
373  print('de-opt case 3.2: ', marr.lastIndexOf(500)) //: de-opt case 3.2:  -1
374}
375lastIndexOfCase3()
376
377function lastIndexOfCase4 () {
378  print('case 4 lastIndexOf') //: case 4 lastIndexOf
379  let arr1 = [1, 2]
380  let arr2 = [1, 2]
381  let notArray = {
382    lastIndexOf (x: any) {
383      return -100
384    }
385  }
386  //aot: [trace] aot call builtin: Object.SetPrototypeOf, caller function name:#*#lastIndexOfCase4@builtinArrayLastIndexOf
387  Object.setPrototypeOf(arr2, notArray)
388
389  //aot: [trace] Check Type: NotStableArray1
390  print('de-opt case 4.1: ', arr1.lastIndexOf(1)) //: de-opt case 4.1:  0
391  print('de-opt case 4.2: ', arr2.lastIndexOf(1)) //: de-opt case 4.2:  -100
392}
393lastIndexOfCase4()
394
395function lastIndexOfCase5 () {
396  print('case 5 lastIndexOf') //: case 5 lastIndexOf
397  let arr1 = [1, 2]
398  Array.prototype.lastIndexOf = function (x: any) {
399    return x
400  }
401
402  //aot: [trace] Check Type: NotStableArray1
403  print('de-opt case 5.1: ', arr1.lastIndexOf(300)) //: de-opt case 5.1:  300
404}
405lastIndexOfCase5()
406