1/*
2 * Copyright (c) 2024 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}
19declare function print(arg:any):string;
20var x = [1,2.1,-1,null,undefined,,false,NaN]
21//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
22print(x.pop()) //: NaN
23//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
24print(x.pop(undefined)) //: false
25//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
26print(x.pop(1,2,3,4,5,6,7,8)) //: undefined
27var y = new Array(10)
28for (let i = 0; i < y.length; i++) {
29    y[i] = i
30}
31//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
32print(y.pop()) //: 9
33//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
34print(y.pop(undefined)) //: 8
35//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
36print(y.pop(1,2,3,4,5,6,7,8)) //: 7
37
38// Check inside try-block
39try {
40  //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
41  print(y.pop()) //: 6
42} catch(e) { 
43}
44
45let obj = {};
46obj.valueOf = (() => { return 5; })
47//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
48print(y.pop(obj)); //: 5
49
50function Throwing() {
51    this.value = 2;
52    Throwing.prototype.valueOf = function() {
53        if (this.value > 0) {
54            throw new Error("positive");
55        }
56        return this.value;
57    }
58}
59let throwingObj = new Throwing();
60try {
61    //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
62    print(y.pop(throwingObj)); //: 4
63} catch(e) {
64    print(e);
65} finally {
66    //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:func_main_0@builtinArrayPop
67    print(y.pop(obj)); //: 3
68}
69
70// Replace standard builtin
71function replace(a : any) {
72  return a;
73}
74
75let newArr = [1, 2, NaN]
76let true_pop = newArr.pop
77newArr.pop = replace
78
79print(newArr.pop(undefined)); //: undefined
80newArr.pop = true_pop
81//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
82print(newArr.pop(undefined)); //: NaN
83
84
85function doPop(x: any): any {
86  return newArr.pop(x);
87}
88
89function printPop(x: any) {
90  try {
91      print(doPop(x));
92  } finally {
93  }
94}
95
96if (ArkTools.isAOTCompiled(printPop)) {
97  // Replace standard builtin after call to standard builtin was profiled
98  newArr.pop = replace
99}
100printPop(-1); //pgo: 2
101//aot: [trace] Check Type: NotCallTarget1
102//aot: -1
103
104printPop("abc"); //pgo: 1
105//aot: [trace] Check Type: NotCallTarget1
106//aot: abc
107
108newArr.pop = true_pop
109
110function popCase1() {
111  print('case 1 pop') //: case 1 pop
112  let arr1 = [1, 2]
113  let arr2 = [1, 2]
114  arr2.garbage = function(x: any): any {
115      return undefined;
116  }
117  //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:#*#popCase1@builtinArrayPop
118  print(arr1.pop()); //: 2
119  print(arr2.pop()); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
120                     //: 2
121}
122popCase1()
123
124
125function popCase2() {
126  print('case 2 pop') //: case 2 pop
127  let arr1 = [1, 2]
128  let arr2 = [1, 2]
129  arr2.pop = function(x: any) {
130      return x
131  }
132
133  //aot: [trace] aot inline builtin: Object.getPrototypeOf, caller function name:#*#popCase2@builtinArrayPop
134  print(Object.getPrototypeOf(arr2) === Array.prototype) //: true
135
136  //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:#*#popCase2@builtinArrayPop
137  print(arr1.pop(1)); //: 2
138  print(arr2.pop(1)); //: 1
139}
140popCase2()
141
142
143function popCase3() {
144  print('case 3 pop') //: case 3 pop
145  let marr = [1, 2]
146  let true_pop = marr.pop
147  let mimicArray = {
148      pop: true_pop,
149  }
150
151  //aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:#*#popCase3@builtinArrayPop
152  print(marr.pop(500)); //: 2
153  Object.setPrototypeOf(marr, mimicArray)
154
155  //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
156  print(marr.pop()); //: 1
157}
158popCase3()
159
160
161function popCase4() {
162  print('case 4 pop') //: case 4 pop
163  let arr1 = [1, 2]
164  let arr2 = [1, 2]
165  let notArray = {
166      pop(x: any) {
167          return -100
168      }
169  }
170  Object.setPrototypeOf(arr2, notArray)
171
172  //aot: [trace] Check Type: NotStableArray1
173  print(arr1.pop(1)); //: 2
174  print(arr2.pop(1)); //: -100
175}
176popCase4()
177
178
179function popCase5() {
180  print('case 5 pop') //: case 5 pop
181  let arr1 = [1, 2]
182  Array.prototype.pop = function(x: any) {
183      return x
184  }
185
186  //aot: [trace] Check Type: NotStableArray1
187  print(arr1.pop(1)); //: 1
188}
189popCase5()
190