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 18namespace panda::ecmascript::kungfu { 19 20GateRef 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 78void 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