1 /*
2 * Copyright (c) 2022 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
16 #include "ecmascript/compiler/hash_stub_builder.h"
17
18 namespace panda::ecmascript::kungfu {
19
GetHash(GateRef key)20 GateRef HashStubBuilder::GetHash(GateRef key)
21 {
22 auto env = GetEnvironment();
23 Label entryLabel(env);
24 Label exit(env);
25 env->SubCfgEntry(&entryLabel);
26 DEFVARIABLE(res, VariableType::INT32(), Int32(0));
27 Label intKey(env);
28 Label symbolCheck(env);
29 BRANCH(TaggedIsInt(key), &intKey, &symbolCheck);
30 Bind(&intKey);
31 res = TaggedGetInt(key);
32 Jump(&exit);
33 Bind(&symbolCheck);
34 Label slowGetHash(env);
35 Label symbolKey(env);
36 Label stringCheck(env);
37 BRANCH(TaggedIsSymbol(key), &symbolKey, &stringCheck);
38
39 Bind(&symbolKey);
40 res = Load(VariableType::INT32(), key, IntPtr(JSSymbol::HASHFIELD_OFFSET));
41 Jump(&exit);
42 Bind(&stringCheck);
43 Label stringKey(env);
44 Label objectCheck(env);
45 BRANCH(TaggedIsString(key), &stringKey, &objectCheck);
46 Bind(&stringKey);
47 res = GetHashcodeFromString(glue_, key);
48 Jump(&exit);
49
50 Bind(&objectCheck);
51 Label heapObjectKey(env);
52 Label numberCheck(env);
53 BRANCH(TaggedIsHeapObject(key), &heapObjectKey, &numberCheck);
54
55 Bind(&heapObjectKey);
56 Label ecmaObjectKey(env);
57 BRANCH(TaggedObjectIsEcmaObject(key), &ecmaObjectKey, &slowGetHash);
58 Bind(&ecmaObjectKey);
59 CalcHashcodeForObject(glue_, key, &res, &exit);
60
61 Bind(&numberCheck);
62 Label numberKey(env);
63 BRANCH(TaggedIsNumber(key), &numberKey, &slowGetHash);
64
65 Bind(&numberKey);
66 CalcHashcodeForNumber(key, &res, &exit);
67
68 Bind(&slowGetHash);
69 res = GetInt32OfTInt(CallRuntime(glue_, RTSTUB_ID(GetLinkedHash), { key }));
70 Jump(&exit);
71
72 Bind(&exit);
73 auto ret = *res;
74 env->SubCfgExit();
75 return ret;
76 }
77
CalcHashcodeForNumber(GateRef key,Variable * res,Label * exit)78 void HashStubBuilder::CalcHashcodeForNumber(GateRef key, Variable *res, Label *exit)
79 {
80 auto env = GetEnvironment();
81 Label doubleKey(env);
82 Label intKey(env);
83 BRANCH(TaggedIsDouble(key), &doubleKey, &intKey);
84 Bind(&doubleKey);
85 {
86 CalcHashcodeForDouble(key, res, exit);
87 }
88 Bind(&intKey);
89 {
90 *res = CalcHashcodeForInt(key);
91 Jump(exit);
92 }
93 }
94 } // namespace panda::ecmascript::kungfu
95