2021-09-04 08:06:49 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ecmascript/compiler/gate.h"
|
2022-01-19 01:11:02 +00:00
|
|
|
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
2021-09-04 08:06:49 +00:00
|
|
|
|
2021-12-23 06:55:22 +00:00
|
|
|
namespace panda::ecmascript::kungfu {
|
2021-09-04 08:06:49 +00:00
|
|
|
constexpr size_t ONE_DEPEND = 1;
|
|
|
|
constexpr size_t MANY_DEPEND = 2;
|
|
|
|
constexpr size_t NO_DEPEND = 0;
|
|
|
|
// NOLINTNEXTLINE(readability-function-size)
|
|
|
|
Properties OpCode::GetProperties() const
|
|
|
|
{
|
|
|
|
// general schema: [STATE]s + [DEPEND]s + [VALUE]s + [ROOT]
|
|
|
|
// GENERAL_STATE for any opcode match in
|
|
|
|
// {IF_TRUE, IF_FALSE, SWITCH_CASE, DEFAULT_CASE, MERGE, LOOP_BEGIN, STATE_ENTRY}
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define STATE(...) (std::make_pair(std::vector<OpCode>{__VA_ARGS__}, false))
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
2022-01-27 08:46:57 +00:00
|
|
|
#define VALUE(...) (std::make_pair(std::vector<MachineType>{__VA_ARGS__}, false))
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define MANY_STATE(...) (std::make_pair(std::vector<OpCode>{__VA_ARGS__}, true))
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
2022-01-27 08:46:57 +00:00
|
|
|
#define MANY_VALUE(...) (std::make_pair(std::vector<MachineType>{__VA_ARGS__}, true))
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define NO_STATE (std::nullopt)
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define NO_VALUE (std::nullopt)
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define NO_ROOT (std::nullopt)
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
|
|
#define GENERAL_STATE (NOP)
|
2021-12-17 09:18:10 +00:00
|
|
|
switch (op_) {
|
2021-09-04 08:06:49 +00:00
|
|
|
// SHARED
|
|
|
|
case NOP:
|
|
|
|
case CIRCUIT_ROOT:
|
|
|
|
return {NOVALUE, NO_STATE, NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case STATE_ENTRY:
|
|
|
|
case DEPEND_ENTRY:
|
|
|
|
case FRAMESTATE_ENTRY:
|
|
|
|
case RETURN_LIST:
|
|
|
|
case THROW_LIST:
|
|
|
|
case CONSTANT_LIST:
|
|
|
|
case ALLOCA_LIST:
|
|
|
|
case ARG_LIST:
|
|
|
|
return {NOVALUE, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CIRCUIT_ROOT)};
|
|
|
|
case RETURN:
|
2021-09-26 06:47:20 +00:00
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, VALUE(ANYVALUE), OpCode(RETURN_LIST)};
|
2021-09-04 08:06:49 +00:00
|
|
|
case THROW:
|
2022-01-27 08:46:57 +00:00
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, VALUE(JSMachineType()), OpCode(THROW_LIST)};
|
2021-09-04 08:06:49 +00:00
|
|
|
case ORDINARY_BLOCK:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case IF_BRANCH:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, VALUE(INT1), NO_ROOT};
|
|
|
|
case SWITCH_BRANCH:
|
2022-01-11 13:09:24 +00:00
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
2021-09-04 08:06:49 +00:00
|
|
|
case IF_TRUE:
|
|
|
|
case IF_FALSE:
|
|
|
|
return {NOVALUE, STATE(OpCode(IF_BRANCH)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case SWITCH_CASE:
|
|
|
|
case DEFAULT_CASE:
|
|
|
|
return {NOVALUE, STATE(OpCode(SWITCH_BRANCH)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case MERGE:
|
|
|
|
return {NOVALUE, MANY_STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case LOOP_BEGIN:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE), OpCode(LOOP_BACK)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case LOOP_BACK:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
2022-01-11 13:09:24 +00:00
|
|
|
case VALUE_SELECTOR:
|
|
|
|
return {FLEX, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(FLEX), NO_ROOT};
|
2021-09-04 08:06:49 +00:00
|
|
|
case DEPEND_SELECTOR:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), MANY_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case DEPEND_RELAY:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case DEPEND_AND:
|
|
|
|
return {NOVALUE, NO_STATE, MANY_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
// High Level IR
|
2021-12-30 17:38:35 +00:00
|
|
|
case JS_BYTECODE:
|
2022-01-27 08:46:57 +00:00
|
|
|
return {FLEX, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, MANY_VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case IF_SUCCESS:
|
|
|
|
case IF_EXCEPTION:
|
|
|
|
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
|
|
|
|
case EXCEPTION_VALUE:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(FLEX), NO_ROOT};
|
|
|
|
case EXCEPTION_DEPEND:
|
|
|
|
return {NOVALUE, NO_STATE, ONE_DEPEND, NO_VALUE, NO_ROOT};
|
2021-09-04 08:06:49 +00:00
|
|
|
// Middle Level IR
|
|
|
|
case CALL:
|
2022-01-11 13:09:24 +00:00
|
|
|
return {FLEX, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
|
2021-09-04 08:06:49 +00:00
|
|
|
case ALLOCA:
|
2022-01-11 13:09:24 +00:00
|
|
|
return {ARCH, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ALLOCA_LIST)};
|
|
|
|
case ARG:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
|
2021-09-04 08:06:49 +00:00
|
|
|
case MUTABLE_DATA:
|
|
|
|
case CONST_DATA:
|
2022-01-11 13:09:24 +00:00
|
|
|
return {ARCH, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
|
|
|
|
case CONSTANT:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
|
|
|
|
case ZEXT_TO_INT64:
|
|
|
|
return {INT64, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case ZEXT_TO_INT32:
|
|
|
|
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case SEXT_TO_INT64:
|
2021-12-17 09:18:10 +00:00
|
|
|
return {INT64, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
2022-01-11 13:09:24 +00:00
|
|
|
case SEXT_TO_INT32:
|
|
|
|
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case TRUNC_TO_INT32:
|
|
|
|
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case TRUNC_TO_INT1:
|
|
|
|
return {INT1, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case REV:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(FLEX), NO_ROOT};
|
|
|
|
case ADD:
|
|
|
|
case SUB:
|
|
|
|
case MUL:
|
|
|
|
case EXP:
|
|
|
|
case SDIV:
|
|
|
|
case SMOD:
|
|
|
|
case UDIV:
|
|
|
|
case UMOD:
|
|
|
|
case FDIV:
|
|
|
|
case FMOD:
|
|
|
|
case AND:
|
|
|
|
case XOR:
|
|
|
|
case OR:
|
|
|
|
case LSL:
|
|
|
|
case LSR:
|
|
|
|
case ASR:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(FLEX, FLEX), NO_ROOT};
|
|
|
|
case SLT:
|
|
|
|
case SLE:
|
|
|
|
case SGT:
|
|
|
|
case SGE:
|
|
|
|
case ULT:
|
|
|
|
case ULE:
|
|
|
|
case UGT:
|
|
|
|
case UGE:
|
|
|
|
case FLT:
|
|
|
|
case FLE:
|
|
|
|
case FGT:
|
|
|
|
case FGE:
|
|
|
|
case EQ:
|
|
|
|
case NE:
|
|
|
|
return {INT1, NO_STATE, NO_DEPEND, VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
|
|
|
|
case LOAD:
|
|
|
|
return {FLEX, NO_STATE, ONE_DEPEND, VALUE(ARCH), NO_ROOT};
|
|
|
|
case STORE:
|
|
|
|
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE, ARCH), NO_ROOT};
|
|
|
|
case TAGGED_TO_INT64:
|
|
|
|
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
|
|
|
|
case SIGNED_INT_TO_FLOAT:
|
|
|
|
case UNSIGNED_INT_TO_FLOAT:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case FLOAT_TO_SIGNED_INT:
|
|
|
|
case UNSIGNED_FLOAT_TO_INT:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
|
|
|
case BITCAST:
|
|
|
|
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
|
2021-09-04 08:06:49 +00:00
|
|
|
default:
|
2021-12-17 09:18:10 +00:00
|
|
|
std::cerr << "Please complete OpCode properties (OpCode=" << op_ << ")" << std::endl;
|
2021-09-04 08:06:49 +00:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
#undef STATE
|
|
|
|
#undef VALUE
|
|
|
|
#undef MANY_STATE
|
|
|
|
#undef MANY_VALUE
|
|
|
|
#undef NO_STATE
|
|
|
|
#undef NO_VALUE
|
|
|
|
#undef NO_ROOT
|
|
|
|
#undef GENERAL_STATE
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string OpCode::Str() const
|
|
|
|
{
|
|
|
|
const std::map<GateOp, const char *> strMap = {
|
|
|
|
{NOP, "NOP"},
|
|
|
|
{CIRCUIT_ROOT, "CIRCUIT_ROOT"},
|
|
|
|
{STATE_ENTRY, "STATE_ENTRY"},
|
|
|
|
{DEPEND_ENTRY, "DEPEND_ENTRY"},
|
|
|
|
{FRAMESTATE_ENTRY, "FRAMESTATE_ENTRY"},
|
|
|
|
{RETURN_LIST, "RETURN_LIST"},
|
|
|
|
{THROW_LIST, "THROW_LIST"},
|
|
|
|
{CONSTANT_LIST, "CONSTANT_LIST"},
|
|
|
|
{ALLOCA_LIST, "ALLOCA_LIST"},
|
|
|
|
{ARG_LIST, "ARG_LIST"},
|
|
|
|
{RETURN, "RETURN"},
|
2021-12-17 09:18:10 +00:00
|
|
|
{RETURN_VOID, "RETURN_VOID"},
|
2021-09-04 08:06:49 +00:00
|
|
|
{THROW, "THROW"},
|
|
|
|
{ORDINARY_BLOCK, "ORDINARY_BLOCK"},
|
|
|
|
{IF_BRANCH, "IF_BRANCH"},
|
|
|
|
{SWITCH_BRANCH, "SWITCH_BRANCH"},
|
|
|
|
{IF_TRUE, "IF_TRUE"},
|
|
|
|
{IF_FALSE, "IF_FALSE"},
|
|
|
|
{SWITCH_CASE, "SWITCH_CASE"},
|
|
|
|
{DEFAULT_CASE, "DEFAULT_CASE"},
|
|
|
|
{MERGE, "MERGE"},
|
|
|
|
{LOOP_BEGIN, "LOOP_BEGIN"},
|
|
|
|
{LOOP_BACK, "LOOP_BACK"},
|
2022-01-11 13:09:24 +00:00
|
|
|
{VALUE_SELECTOR, "VALUE_SELECTOR"},
|
2021-09-04 08:06:49 +00:00
|
|
|
{DEPEND_SELECTOR, "DEPEND_SELECTOR"},
|
|
|
|
{DEPEND_RELAY, "DEPEND_RELAY"},
|
|
|
|
{DEPEND_AND, "DEPEND_AND"},
|
2021-12-30 17:38:35 +00:00
|
|
|
{JS_BYTECODE, "JS_BYTECODE"},
|
2022-01-27 08:46:57 +00:00
|
|
|
{IF_SUCCESS, "IF_SUCCESS"},
|
|
|
|
{IF_EXCEPTION, "IF_EXCEPTION"},
|
|
|
|
{EXCEPTION_VALUE, "EXCEPTION_VALUE"},
|
|
|
|
{EXCEPTION_DEPEND, "EXCEPTION_DEPEND"},
|
2021-09-04 08:06:49 +00:00
|
|
|
{CALL, "CALL"},
|
|
|
|
{ALLOCA, "ALLOCA"},
|
2022-01-11 13:09:24 +00:00
|
|
|
{ARG, "ARG"},
|
2021-09-04 08:06:49 +00:00
|
|
|
{MUTABLE_DATA, "MUTABLE_DATA"},
|
|
|
|
{CONST_DATA, "CONST_DATA"},
|
2022-01-11 13:09:24 +00:00
|
|
|
{CONSTANT, "CONSTANT"},
|
|
|
|
{ZEXT_TO_INT64, "ZEXT_TO_INT64"},
|
|
|
|
{ZEXT_TO_INT32, "ZEXT_TO_INT32"},
|
|
|
|
{SEXT_TO_INT64, "SEXT_TO_INT64"},
|
|
|
|
{SEXT_TO_INT32, "SEXT_TO_INT32"},
|
|
|
|
{TRUNC_TO_INT32, "TRUNC_TO_INT32"},
|
|
|
|
{TRUNC_TO_INT1, "TRUNC_TO_INT1"},
|
|
|
|
{REV, "REV"},
|
|
|
|
{ADD, "ADD"},
|
|
|
|
{SUB, "SUB"},
|
|
|
|
{MUL, "MUL"},
|
|
|
|
{EXP, "EXP"},
|
|
|
|
{SDIV, "SDIV"},
|
|
|
|
{SMOD, "SMOD"},
|
|
|
|
{UDIV, "UDIV"},
|
|
|
|
{UMOD, "UMOD"},
|
|
|
|
{FDIV, "FDIV"},
|
|
|
|
{FMOD, "FMOD"},
|
|
|
|
{AND, "AND"},
|
|
|
|
{XOR, "XOR"},
|
|
|
|
{OR, "OR"},
|
|
|
|
{LSL, "LSL"},
|
|
|
|
{LSR, "LSR"},
|
|
|
|
{ASR, "ASR"},
|
|
|
|
{SLT, "SLT"},
|
|
|
|
{SLE, "SLE"},
|
|
|
|
{SGT, "SGT"},
|
|
|
|
{SGE, "SGE"},
|
|
|
|
{ULT, "ULT"},
|
|
|
|
{ULE, "ULE"},
|
|
|
|
{UGT, "UGT"},
|
|
|
|
{UGE, "UGE"},
|
|
|
|
{FLT, "FLT"},
|
|
|
|
{FLE, "FLE"},
|
|
|
|
{FGT, "FGT"},
|
|
|
|
{FGE, "FGE"},
|
|
|
|
{EQ, "EQ"},
|
|
|
|
{NE, "NE"},
|
|
|
|
{LOAD, "LOAD"},
|
|
|
|
{STORE, "STORE"},
|
|
|
|
{TAGGED_TO_INT64, "TAGGED_TO_INT64"},
|
|
|
|
{SIGNED_INT_TO_FLOAT, "SIGNED_INT_TO_FLOAT"},
|
|
|
|
{UNSIGNED_INT_TO_FLOAT, "UNSIGNED_INT_TO_FLOAT"},
|
|
|
|
{FLOAT_TO_SIGNED_INT, "FLOAT_TO_SIGNED_INT"},
|
|
|
|
{UNSIGNED_FLOAT_TO_INT, "UNSIGNED_FLOAT_TO_INT"},
|
|
|
|
{BITCAST, "BITCAST"},
|
2021-09-04 08:06:49 +00:00
|
|
|
};
|
2021-12-17 09:18:10 +00:00
|
|
|
if (strMap.count(op_) > 0) {
|
|
|
|
return strMap.at(op_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2021-12-17 09:18:10 +00:00
|
|
|
return "OP-" + std::to_string(op_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
// 4 : 4 means that there are 4 args in total
|
|
|
|
std::array<size_t, 4> OpCode::GetOpCodeNumInsArray(BitField bitfield) const
|
|
|
|
{
|
|
|
|
const size_t manyDepend = 2;
|
2021-12-17 09:18:10 +00:00
|
|
|
auto properties = GetProperties();
|
2021-09-04 08:06:49 +00:00
|
|
|
auto stateProp = properties.statesIn;
|
|
|
|
auto dependProp = properties.dependsIn;
|
|
|
|
auto valueProp = properties.valuesIn;
|
|
|
|
auto rootProp = properties.states;
|
|
|
|
size_t stateSize = stateProp.has_value() ? (stateProp->second ? bitfield : stateProp->first.size()) : 0;
|
|
|
|
size_t dependSize = (dependProp == manyDepend) ? bitfield : dependProp;
|
|
|
|
size_t valueSize = valueProp.has_value() ? (valueProp->second ? bitfield : valueProp->first.size()) : 0;
|
|
|
|
size_t rootSize = rootProp.has_value() ? 1 : 0;
|
|
|
|
return {stateSize, dependSize, valueSize, rootSize};
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t OpCode::GetOpCodeNumIns(BitField bitfield) const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto numInsArray = GetOpCodeNumInsArray(bitfield);
|
2021-09-04 08:06:49 +00:00
|
|
|
// 2 : 2 means the third element.
|
|
|
|
// 3 : 3 means the fourth element.
|
|
|
|
return numInsArray[0] + numInsArray[1] + numInsArray[2] + numInsArray[3];
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
MachineType OpCode::GetMachineType() const
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetProperties().returnValue;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
MachineType OpCode::GetInMachineType(BitField bitfield, size_t idx) const
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto numInsArray = GetOpCodeNumInsArray(bitfield);
|
|
|
|
auto valueProp = GetProperties().valuesIn;
|
2021-09-04 08:06:49 +00:00
|
|
|
idx -= numInsArray[0];
|
|
|
|
idx -= numInsArray[1];
|
|
|
|
ASSERT(valueProp.has_value());
|
|
|
|
if (valueProp->second) {
|
|
|
|
return valueProp->first.at(std::min(idx, valueProp->first.size() - 1));
|
|
|
|
}
|
|
|
|
return valueProp->first.at(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
OpCode OpCode::GetInStateCode(size_t idx) const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto stateProp = GetProperties().statesIn;
|
2021-09-04 08:06:49 +00:00
|
|
|
ASSERT(stateProp.has_value());
|
|
|
|
if (stateProp->second) {
|
|
|
|
return stateProp->first.at(std::min(idx, stateProp->first.size() - 1));
|
|
|
|
}
|
|
|
|
return stateProp->first.at(idx);
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
std::string MachineTypeToStr(MachineType machineType)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-01-27 08:46:57 +00:00
|
|
|
switch (machineType) {
|
2021-09-04 08:06:49 +00:00
|
|
|
case NOVALUE:
|
|
|
|
return "NOVALUE";
|
|
|
|
case ANYVALUE:
|
|
|
|
return "ANYVALUE";
|
|
|
|
case INT1:
|
|
|
|
return "INT1";
|
|
|
|
case INT8:
|
|
|
|
return "INT8";
|
|
|
|
case INT16:
|
|
|
|
return "INT16";
|
|
|
|
case INT32:
|
|
|
|
return "INT32";
|
|
|
|
case INT64:
|
|
|
|
return "INT64";
|
|
|
|
case FLOAT32:
|
|
|
|
return "FLOAT32";
|
|
|
|
case FLOAT64:
|
|
|
|
return "FLOAT64";
|
|
|
|
default:
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckNullInput() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
const auto numIns = GetNumIns();
|
2021-09-04 08:06:49 +00:00
|
|
|
for (size_t idx = 0; idx < numIns; idx++) {
|
2021-12-17 09:18:10 +00:00
|
|
|
if (IsInGateNull(idx)) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return std::make_pair("In list contains null", idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckStateInput() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
const auto numInsArray = GetOpCode().GetOpCodeNumInsArray(GetBitField());
|
2021-09-04 08:06:49 +00:00
|
|
|
size_t stateStart = 0;
|
|
|
|
size_t stateEnd = numInsArray[0];
|
|
|
|
for (size_t idx = stateStart; idx < stateEnd; idx++) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto stateProp = GetOpCode().GetProperties().statesIn;
|
2021-09-04 08:06:49 +00:00
|
|
|
ASSERT(stateProp.has_value());
|
2021-12-17 09:18:10 +00:00
|
|
|
auto expectedIn = GetOpCode().GetInStateCode(idx);
|
|
|
|
auto actualIn = GetInGateConst(idx)->GetOpCode();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (expectedIn == OpCode::NOP) { // general
|
|
|
|
if (!actualIn.IsGeneralState()) {
|
|
|
|
return std::make_pair(
|
|
|
|
"State input does not match (expected:<General State> actual:" + actualIn.Str() + ")", idx);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (expectedIn != actualIn) {
|
|
|
|
return std::make_pair(
|
|
|
|
"State input does not match (expected:" + expectedIn.Str() + " actual:" + actualIn.Str() + ")",
|
|
|
|
idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckValueInput() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
const auto numInsArray = GetOpCode().GetOpCodeNumInsArray(GetBitField());
|
2021-09-04 08:06:49 +00:00
|
|
|
size_t valueStart = numInsArray[0] + numInsArray[1];
|
|
|
|
size_t valueEnd = numInsArray[0] + numInsArray[1] + numInsArray[2]; // 2 : 2 means the third element.
|
|
|
|
for (size_t idx = valueStart; idx < valueEnd; idx++) {
|
2022-01-27 08:46:57 +00:00
|
|
|
auto expectedIn = GetOpCode().GetInMachineType(GetBitField(), idx);
|
|
|
|
auto actualIn = GetInGateConst(idx)->GetOpCode().GetMachineType();
|
|
|
|
if (expectedIn == MachineType::FLEX) {
|
|
|
|
expectedIn = GetMachineType();
|
2022-01-11 13:09:24 +00:00
|
|
|
}
|
2022-01-27 08:46:57 +00:00
|
|
|
if (actualIn == MachineType::FLEX) {
|
|
|
|
actualIn = GetInGateConst(idx)->GetMachineType();
|
2022-01-11 13:09:24 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
if ((expectedIn != actualIn) && (expectedIn != ANYVALUE)) {
|
2022-01-27 08:46:57 +00:00
|
|
|
return std::make_pair("Value input does not match (expected: " + MachineTypeToStr(expectedIn) +
|
|
|
|
" actual: " + MachineTypeToStr(actualIn) + ")",
|
2021-09-04 08:06:49 +00:00
|
|
|
idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckDependInput() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
const auto numInsArray = GetOpCode().GetOpCodeNumInsArray(GetBitField());
|
2021-09-04 08:06:49 +00:00
|
|
|
size_t dependStart = numInsArray[0];
|
|
|
|
size_t dependEnd = dependStart + numInsArray[1];
|
|
|
|
for (size_t idx = dependStart; idx < dependEnd; idx++) {
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetInGateConst(idx)->GetNumInsArray()[1] == 0 &&
|
|
|
|
GetInGateConst(idx)->GetOpCode() != OpCode::DEPEND_ENTRY) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return std::make_pair("Depend input is side-effect free", idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckStateOutput() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode().IsState()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
size_t cnt = 0;
|
|
|
|
const Gate *curGate = this;
|
|
|
|
if (!curGate->IsFirstOutNull()) {
|
|
|
|
const Out *curOut = curGate->GetFirstOutConst();
|
|
|
|
if (curOut->GetGateConst()->GetOpCode().IsState()) {
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
while (!curOut->IsNextOutNull()) {
|
|
|
|
curOut = curOut->GetNextOutConst();
|
|
|
|
if (curOut->GetGateConst()->GetOpCode().IsState()) {
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size_t expected = 0;
|
|
|
|
bool needCheck = true;
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode().IsTerminalState()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
expected = 0;
|
2021-12-17 09:18:10 +00:00
|
|
|
} else if (GetOpCode() == OpCode::IF_BRANCH) {
|
2021-09-04 08:06:49 +00:00
|
|
|
expected = 2; // 2: expected number of state out branches
|
2021-12-17 09:18:10 +00:00
|
|
|
} else if (GetOpCode() == OpCode::SWITCH_BRANCH) {
|
2021-09-04 08:06:49 +00:00
|
|
|
needCheck = false;
|
|
|
|
} else {
|
|
|
|
expected = 1;
|
|
|
|
}
|
|
|
|
if (needCheck && cnt != expected) {
|
|
|
|
return std::make_pair("Number of state out branches is not valid (expected:" + std::to_string(expected) +
|
|
|
|
" actual:" + std::to_string(cnt) + ")",
|
|
|
|
-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckBranchOutput() const
|
|
|
|
{
|
|
|
|
std::map<std::pair<OpCode, BitField>, size_t> setOfOps;
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode() == OpCode::IF_BRANCH || GetOpCode() == OpCode::SWITCH_BRANCH) {
|
2021-09-04 08:06:49 +00:00
|
|
|
size_t cnt = 0;
|
|
|
|
const Gate *curGate = this;
|
|
|
|
if (!curGate->IsFirstOutNull()) {
|
|
|
|
const Out *curOut = curGate->GetFirstOutConst();
|
|
|
|
if (curOut->GetGateConst()->GetOpCode().IsState()) {
|
|
|
|
setOfOps[{curOut->GetGateConst()->GetOpCode(), curOut->GetGateConst()->GetBitField()}]++;
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
while (!curOut->IsNextOutNull()) {
|
|
|
|
curOut = curOut->GetNextOutConst();
|
|
|
|
if (curOut->GetGateConst()->GetOpCode().IsState()) {
|
|
|
|
setOfOps[{curOut->GetGateConst()->GetOpCode(), curOut->GetGateConst()->GetBitField()}]++;
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (setOfOps.size() != cnt) {
|
|
|
|
return std::make_pair("Duplicate state out branches", -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckNOP() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode() == OpCode::NOP) {
|
|
|
|
if (!IsFirstOutNull()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return std::make_pair("NOP gate used by other gates", -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckSelector() const
|
|
|
|
{
|
2022-01-11 13:09:24 +00:00
|
|
|
if (GetOpCode() == OpCode::VALUE_SELECTOR || GetOpCode() == OpCode::DEPEND_SELECTOR) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto stateOp = GetInGateConst(0)->GetOpCode();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (stateOp == OpCode::MERGE || stateOp == OpCode::LOOP_BEGIN) {
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetInGateConst(0)->GetNumIns() != GetNumIns() - 1) {
|
|
|
|
if (GetOpCode() == OpCode::DEPEND_SELECTOR) {
|
2021-09-04 08:06:49 +00:00
|
|
|
return std::make_pair("Number of depend flows does not match control flows (expected:" +
|
2021-12-17 09:18:10 +00:00
|
|
|
std::to_string(GetInGateConst(0)->GetNumIns()) +
|
|
|
|
" actual:" + std::to_string(GetNumIns() - 1) + ")",
|
2021-09-04 08:06:49 +00:00
|
|
|
-1);
|
|
|
|
} else {
|
|
|
|
return std::make_pair("Number of data flows does not match control flows (expected:" +
|
2021-12-17 09:18:10 +00:00
|
|
|
std::to_string(GetInGateConst(0)->GetNumIns()) +
|
|
|
|
" actual:" + std::to_string(GetNumIns() - 1) + ")",
|
2021-09-04 08:06:49 +00:00
|
|
|
-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return std::make_pair(
|
|
|
|
"State input does not match (expected:[MERGE|LOOP_BEGIN] actual:" + stateOp.Str() + ")", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::CheckRelay() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode() == OpCode::DEPEND_RELAY) {
|
|
|
|
auto stateOp = GetInGateConst(0)->GetOpCode();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (!(stateOp == OpCode::IF_TRUE || stateOp == OpCode::IF_FALSE || stateOp == OpCode::SWITCH_CASE ||
|
2021-12-30 17:38:35 +00:00
|
|
|
stateOp == OpCode::DEFAULT_CASE || stateOp == OpCode::IF_SUCCESS || stateOp == OpCode::IF_EXCEPTION)) {
|
2022-01-19 01:11:02 +00:00
|
|
|
return std::make_pair("State input does not match ("
|
|
|
|
"expected:[IF_TRUE|IF_FALSE|SWITCH_CASE|DEFAULT_CASE|IF_SUCCESS|IF_EXCEPTION] actual:" +
|
|
|
|
stateOp.Str() + ")", 0);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::pair<std::string, size_t>> Gate::SpecialCheck() const
|
|
|
|
{
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckNOP();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckSelector();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckRelay();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Gate::Verify() const
|
|
|
|
{
|
|
|
|
std::string errorString;
|
|
|
|
size_t highlightIdx = -1;
|
|
|
|
bool failed = false;
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckNullInput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckStateInput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckValueInput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckDependInput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckStateOutput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = CheckBranchOutput();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!failed) {
|
2021-12-17 09:18:10 +00:00
|
|
|
auto ret = SpecialCheck();
|
2021-09-04 08:06:49 +00:00
|
|
|
if (ret.has_value()) {
|
|
|
|
failed = true;
|
|
|
|
std::tie(errorString, highlightIdx) = ret.value();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (failed) {
|
|
|
|
std::cerr << "[Verifier][Error] Gate level input list schema verify failed" << std::endl;
|
2022-01-22 11:09:02 +00:00
|
|
|
Print("", true, highlightIdx);
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << "Note: " << errorString << std::endl;
|
|
|
|
}
|
|
|
|
return !failed;
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
MachineType JSMachineType()
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2022-01-27 08:46:57 +00:00
|
|
|
return MachineType::INT64;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t GetOpCodeNumIns(OpCode opcode, BitField bitfield)
|
|
|
|
{
|
|
|
|
return opcode.GetOpCodeNumIns(bitfield);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Out::SetNextOut(const Out *ptr)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
nextOut_ =
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
static_cast<GateRef>((reinterpret_cast<const uint8_t *>(ptr)) - (reinterpret_cast<const uint8_t *>(this)));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Out *Out::GetNextOut()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<Out *>((reinterpret_cast<uint8_t *>(this)) + nextOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Out *Out::GetNextOutConst() const
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<const Out *>((reinterpret_cast<const uint8_t *>(this)) + nextOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Out::SetPrevOut(const Out *ptr)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
prevOut_ =
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
static_cast<GateRef>((reinterpret_cast<const uint8_t *>(ptr)) - (reinterpret_cast<const uint8_t *>(this)));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Out *Out::GetPrevOut()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<Out *>((reinterpret_cast<uint8_t *>(this)) + prevOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Out *Out::GetPrevOutConst() const
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<const Out *>((reinterpret_cast<const uint8_t *>(this)) + prevOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Out::SetIndex(OutIdx idx)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
idx_ = idx;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
OutIdx Out::GetIndex() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return idx_;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Gate *Out::GetGate()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<Gate *>(&this[idx_ + 1]);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Gate *Out::GetGateConst() const
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<const Gate *>(&this[idx_ + 1]);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Out::SetPrevOutNull()
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
prevOut_ = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Out::IsPrevOutNull() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return prevOut_ == 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Out::SetNextOutNull()
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
nextOut_ = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Out::IsNextOutNull() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return nextOut_ == 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void In::SetGate(const Gate *ptr)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
gatePtr_ =
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
static_cast<GateRef>((reinterpret_cast<const uint8_t *>(ptr)) - (reinterpret_cast<const uint8_t *>(this)));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Gate *In::GetGate()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<Gate *>((reinterpret_cast<uint8_t *>(this)) + gatePtr_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Gate *In::GetGateConst() const
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<const Gate *>((reinterpret_cast<const uint8_t *>(this)) + gatePtr_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void In::SetGateNull()
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
gatePtr_ = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool In::IsGateNull() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return gatePtr_ == 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
2022-01-27 08:46:57 +00:00
|
|
|
Gate::Gate(GateId id, OpCode opcode, MachineType bitValue, BitField bitfield, Gate *inList[], GateType type,
|
2022-01-22 11:09:02 +00:00
|
|
|
MarkCode mark)
|
2022-01-19 01:11:02 +00:00
|
|
|
: id_(id), opcode_(opcode), bitValue_(bitValue), type_(type), stamp_(1), mark_(mark), bitfield_(bitfield),
|
|
|
|
firstOut_(0)
|
2022-01-11 13:09:24 +00:00
|
|
|
{
|
|
|
|
auto numIns = GetNumIns();
|
|
|
|
for (size_t idx = 0; idx < numIns; idx++) {
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
auto in = inList[idx];
|
|
|
|
if (in == nullptr) {
|
|
|
|
GetIn(idx)->SetGateNull();
|
|
|
|
} else {
|
|
|
|
NewIn(idx, in);
|
|
|
|
}
|
|
|
|
auto curOut = GetOut(idx);
|
|
|
|
curOut->SetIndex(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
Gate::Gate(GateId id, OpCode opcode, BitField bitfield, Gate *inList[], GateType type, MarkCode mark)
|
2022-01-18 04:02:20 +00:00
|
|
|
: id_(id), opcode_(opcode), type_(type), stamp_(1), mark_(mark), bitfield_(bitfield), firstOut_(0)
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto numIns = GetNumIns();
|
2021-09-04 08:06:49 +00:00
|
|
|
for (size_t idx = 0; idx < numIns; idx++) {
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
auto in = inList[idx];
|
|
|
|
if (in == nullptr) {
|
2021-12-17 09:18:10 +00:00
|
|
|
GetIn(idx)->SetGateNull();
|
2021-09-04 08:06:49 +00:00
|
|
|
} else {
|
2021-12-17 09:18:10 +00:00
|
|
|
NewIn(idx, in);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2021-12-17 09:18:10 +00:00
|
|
|
auto curOut = GetOut(idx);
|
2021-09-04 08:06:49 +00:00
|
|
|
curOut->SetIndex(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetOutListSize(size_t numIns)
|
|
|
|
{
|
|
|
|
return numIns * sizeof(Out);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetOutListSize() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return Gate::GetOutListSize(GetNumIns());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetInListSize(size_t numIns)
|
|
|
|
{
|
|
|
|
return numIns * sizeof(In);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetInListSize() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return Gate::GetInListSize(GetNumIns());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetGateSize(size_t numIns)
|
|
|
|
{
|
|
|
|
return Gate::GetOutListSize(numIns) + Gate::GetInListSize(numIns) + sizeof(Gate);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetGateSize() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return Gate::GetGateSize(GetNumIns());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::NewIn(size_t idx, Gate *in)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
GetIn(idx)->SetGate(in);
|
|
|
|
auto curOut = GetOut(idx);
|
2021-09-04 08:06:49 +00:00
|
|
|
if (in->IsFirstOutNull()) {
|
|
|
|
curOut->SetNextOutNull();
|
|
|
|
} else {
|
|
|
|
curOut->SetNextOut(in->GetFirstOut());
|
|
|
|
in->GetFirstOut()->SetPrevOut(curOut);
|
|
|
|
}
|
|
|
|
curOut->SetPrevOutNull();
|
|
|
|
in->SetFirstOut(curOut);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::ModifyIn(size_t idx, Gate *in)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
DeleteIn(idx);
|
|
|
|
NewIn(idx, in);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::DeleteIn(size_t idx)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
if (!GetOut(idx)->IsNextOutNull() && !GetOut(idx)->IsPrevOutNull()) {
|
|
|
|
GetOut(idx)->GetPrevOut()->SetNextOut(GetOut(idx)->GetNextOut());
|
|
|
|
GetOut(idx)->GetNextOut()->SetPrevOut(GetOut(idx)->GetPrevOut());
|
|
|
|
} else if (GetOut(idx)->IsNextOutNull() && !GetOut(idx)->IsPrevOutNull()) {
|
|
|
|
GetOut(idx)->GetPrevOut()->SetNextOutNull();
|
|
|
|
} else if (!GetOut(idx)->IsNextOutNull()) { // then GetOut(idx)->IsPrevOutNull() is true
|
|
|
|
GetIn(idx)->GetGate()->SetFirstOut(GetOut(idx)->GetNextOut());
|
|
|
|
GetOut(idx)->GetNextOut()->SetPrevOutNull();
|
2021-09-04 08:06:49 +00:00
|
|
|
} else { // only this out now
|
2021-12-17 09:18:10 +00:00
|
|
|
GetIn(idx)->GetGate()->SetFirstOutNull();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2021-12-17 09:18:10 +00:00
|
|
|
GetIn(idx)->SetGateNull();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::DeleteGate()
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
auto numIns = GetNumIns();
|
2021-09-04 08:06:49 +00:00
|
|
|
for (size_t idx = 0; idx < numIns; idx++) {
|
2021-12-17 09:18:10 +00:00
|
|
|
DeleteIn(idx);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2021-12-17 09:18:10 +00:00
|
|
|
SetOpCode(OpCode(OpCode::NOP));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Out *Gate::GetOut(size_t idx)
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
return &reinterpret_cast<Out *>(this)[-1 - idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
Out *Gate::GetFirstOut()
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<Out *>((reinterpret_cast<uint8_t *>(this)) + firstOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Out *Gate::GetFirstOutConst() const
|
|
|
|
{
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
return reinterpret_cast<const Out *>((reinterpret_cast<const uint8_t *>(this)) + firstOut_);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::SetFirstOutNull()
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
firstOut_ = 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Gate::IsFirstOutNull() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return firstOut_ == 0;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::SetFirstOut(const Out *firstOut)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
firstOut_ =
|
2021-09-04 08:06:49 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
2021-12-17 09:18:10 +00:00
|
|
|
static_cast<GateRef>(reinterpret_cast<const uint8_t *>(firstOut) - reinterpret_cast<const uint8_t *>(this));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
In *Gate::GetIn(size_t idx)
|
|
|
|
{
|
|
|
|
#ifndef NDEBUG
|
2021-12-17 09:18:10 +00:00
|
|
|
if (idx >= GetNumIns()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << std::dec << "Gate In access out-of-bound! (idx=" << idx << ")" << std::endl;
|
2021-12-17 09:18:10 +00:00
|
|
|
Print();
|
2021-09-04 08:06:49 +00:00
|
|
|
ASSERT(false);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
return &reinterpret_cast<In *>(this + 1)[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
const In *Gate::GetInConst(size_t idx) const
|
|
|
|
{
|
|
|
|
#ifndef NDEBUG
|
2021-12-17 09:18:10 +00:00
|
|
|
if (idx >= GetNumIns()) {
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << std::dec << "Gate In access out-of-bound! (idx=" << idx << ")" << std::endl;
|
2021-12-17 09:18:10 +00:00
|
|
|
Print();
|
2021-09-04 08:06:49 +00:00
|
|
|
ASSERT(false);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
|
|
|
return &reinterpret_cast<const In *>(this + 1)[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
Gate *Gate::GetInGate(size_t idx)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetIn(idx)->GetGate();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Gate *Gate::GetInGateConst(size_t idx) const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetInConst(idx)->GetGateConst();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Gate::IsInGateNull(size_t idx) const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetInConst(idx)->IsGateNull();
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateId Gate::GetId() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return id_;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
OpCode Gate::GetOpCode() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return opcode_;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
MachineType Gate::GetMachineType() const
|
2022-01-11 13:09:24 +00:00
|
|
|
{
|
|
|
|
return bitValue_;
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
void Gate::SetMachineType(MachineType MachineType)
|
2022-01-11 13:09:24 +00:00
|
|
|
{
|
2022-01-27 08:46:57 +00:00
|
|
|
bitValue_ = MachineType;
|
2022-01-11 13:09:24 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
void Gate::SetOpCode(OpCode opcode)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
opcode_ = opcode;
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
GateType Gate::GetGateType() const
|
2021-12-17 09:18:10 +00:00
|
|
|
{
|
|
|
|
return type_;
|
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
void Gate::SetGateType(GateType type)
|
2021-12-17 09:18:10 +00:00
|
|
|
{
|
|
|
|
type_ = type;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t Gate::GetNumIns() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetOpCodeNumIns(GetOpCode(), GetBitField());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::array<size_t, 4> Gate::GetNumInsArray() const // 4 : 4 means that there are 4 args.
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return GetOpCode().GetOpCodeNumInsArray(GetBitField());
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BitField Gate::GetBitField() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return bitfield_;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::SetBitField(BitField bitfield)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
bitfield_ = bitfield;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-27 08:46:57 +00:00
|
|
|
std::string Gate::MachineTypeStr(MachineType machineType) const
|
2022-01-11 13:09:24 +00:00
|
|
|
{
|
2022-01-27 08:46:57 +00:00
|
|
|
const std::map<MachineType, const char *> strMap = {
|
2022-01-11 13:09:24 +00:00
|
|
|
{NOVALUE, "NOVALUE"},
|
|
|
|
{ANYVALUE, "ANYVALUE"},
|
|
|
|
{ARCH, "ARCH"},
|
|
|
|
{FLEX, "FLEX"},
|
|
|
|
{INT1, "INT1"},
|
|
|
|
{INT8, "INT8"},
|
|
|
|
{INT16, "INT16"},
|
|
|
|
{INT32, "INT32"},
|
|
|
|
{INT64, "INT64"},
|
|
|
|
{FLOAT32, "FLOAT32"},
|
|
|
|
{FLOAT64, "FLOAT64"},
|
|
|
|
};
|
2022-01-27 08:46:57 +00:00
|
|
|
if (strMap.count(machineType) > 0) {
|
|
|
|
return strMap.at(machineType);
|
|
|
|
}
|
|
|
|
return "MachineType-" + std::to_string(machineType);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Gate::GateTypeStr(GateType gateType) const
|
|
|
|
{
|
|
|
|
const std::map<GateType, const char *> strMap = {
|
|
|
|
{C_VALUE, "C_VALUE"},
|
|
|
|
{TAGGED_VALUE, "TAGGED_VALUE"},
|
|
|
|
{TAGGED_POINTER, "TAGGED_POINTER"},
|
|
|
|
{TAGGED_NO_POINTER, "TAGGED_NO_POINTER"},
|
|
|
|
{EMPTY, "EMPTY"},
|
|
|
|
{JS_ANY, "JS_ANY"},
|
|
|
|
};
|
|
|
|
|
|
|
|
if (strMap.count(gateType) > 0) {
|
|
|
|
return strMap.at(gateType);
|
2022-01-11 13:09:24 +00:00
|
|
|
}
|
2022-01-27 08:46:57 +00:00
|
|
|
return "GateType-" + std::to_string(gateType);
|
2022-01-11 13:09:24 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 04:02:20 +00:00
|
|
|
void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx) const
|
2021-09-04 08:06:49 +00:00
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
if (GetOpCode() != OpCode::NOP) {
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << std::dec << "("
|
2021-12-17 09:18:10 +00:00
|
|
|
<< "id=" << id_ << ", "
|
|
|
|
<< "op=" << GetOpCode().Str() << ", "
|
2022-01-18 04:02:20 +00:00
|
|
|
<< ((bytecode.compare("") == 0) ? "" : "bytecode=") << bytecode
|
|
|
|
<< ((bytecode.compare("") == 0) ? "" : ", ")
|
2022-01-27 08:46:57 +00:00
|
|
|
<< "machineType=" << MachineTypeStr(GetMachineType()) << ", "
|
2021-12-17 09:18:10 +00:00
|
|
|
<< "bitfield=" << std::to_string(bitfield_) << ", "
|
2022-01-27 08:46:57 +00:00
|
|
|
<< "type=" << GateTypeStr(type_) << ", "
|
2021-12-17 09:18:10 +00:00
|
|
|
<< "stamp=" << static_cast<uint32_t>(stamp_) << ", "
|
|
|
|
<< "mark=" << static_cast<uint32_t>(mark_) << ", ";
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << "in="
|
|
|
|
<< "[";
|
2022-01-18 04:02:20 +00:00
|
|
|
auto numInsArray = GetOpCode().GetOpCodeNumInsArray(GetBitField());
|
|
|
|
size_t idx = 0;
|
2022-01-22 11:09:02 +00:00
|
|
|
auto stateSize = numInsArray[0];
|
|
|
|
auto dependSize = numInsArray[1];
|
|
|
|
auto valueSize = numInsArray[2]; // 2 : 2 means the third element.
|
|
|
|
auto rootSize = numInsArray[3]; // 3 : 3 means the four element.
|
|
|
|
idx = PrintInGate(stateSize, idx, 0, inListPreview, highlightIdx);
|
|
|
|
idx = PrintInGate(stateSize + dependSize, idx, stateSize, inListPreview, highlightIdx);
|
|
|
|
idx = PrintInGate(stateSize + dependSize + valueSize, idx, stateSize + dependSize, inListPreview, highlightIdx);
|
|
|
|
PrintInGate(stateSize + dependSize + valueSize + rootSize, idx, stateSize + dependSize + valueSize,
|
|
|
|
inListPreview, highlightIdx, true);
|
2022-01-18 04:02:20 +00:00
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << "]"
|
|
|
|
<< ", ";
|
|
|
|
std::cerr << "out="
|
|
|
|
<< "[";
|
2021-12-17 09:18:10 +00:00
|
|
|
if (!IsFirstOutNull()) {
|
|
|
|
const Out *curOut = GetFirstOutConst();
|
2021-09-04 08:06:49 +00:00
|
|
|
std::cerr << std::dec << ""
|
|
|
|
<< std::to_string(curOut->GetGateConst()->GetId()) +
|
|
|
|
(inListPreview ? std::string(":" + curOut->GetGateConst()->GetOpCode().Str()) : std::string(""));
|
|
|
|
while (!curOut->IsNextOutNull()) {
|
|
|
|
curOut = curOut->GetNextOutConst();
|
|
|
|
std::cerr << std::dec << " "
|
|
|
|
<< std::to_string(curOut->GetGateConst()->GetId()) +
|
|
|
|
(inListPreview ? std::string(":" + curOut->GetGateConst()->GetOpCode().Str())
|
|
|
|
: std::string(""));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::cerr << "]"
|
|
|
|
<< ")" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-18 04:02:20 +00:00
|
|
|
size_t Gate::PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx,
|
|
|
|
bool isEnd) const
|
|
|
|
{
|
|
|
|
std::cerr << "[";
|
|
|
|
for (; idx < numIns; idx++) {
|
|
|
|
std::cerr << std::dec << ((idx == size) ? "" : " ") << ((idx == highlightIdx) ? "\033[4;31m" : "")
|
|
|
|
<< ((IsInGateNull(idx)
|
|
|
|
? "N"
|
|
|
|
: (std::to_string(GetInGateConst(idx)->GetId()) +
|
|
|
|
(inListPreview ? std::string(":" + GetInGateConst(idx)->GetOpCode().Str())
|
|
|
|
: std::string("")))))
|
|
|
|
<< ((idx == highlightIdx) ? "\033[0m" : "");
|
|
|
|
}
|
|
|
|
std::cerr << "]"
|
|
|
|
<< ((isEnd) ? "" : ", ");
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::PrintByteCode(std::string bytecode) const
|
|
|
|
{
|
|
|
|
Print(bytecode);
|
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
MarkCode Gate::GetMark(TimeStamp stamp) const
|
|
|
|
{
|
2022-01-27 08:46:57 +00:00
|
|
|
return (stamp_ == stamp) ? mark_ : MarkCode::NO_MARK;
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Gate::SetMark(MarkCode mark, TimeStamp stamp)
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
stamp_ = stamp;
|
|
|
|
mark_ = mark;
|
2021-10-28 07:06:25 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 08:06:49 +00:00
|
|
|
bool OpCode::IsRoot() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (GetProperties().states == OpCode::CIRCUIT_ROOT) || (op_ == OpCode::CIRCUIT_ROOT);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsProlog() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (GetProperties().states == OpCode::ARG_LIST);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsFixed() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (GetOpCodeNumInsArray(1)[0] > 0) &&
|
2022-01-27 08:46:57 +00:00
|
|
|
((GetMachineType() != NOVALUE) ||
|
2021-12-17 09:18:10 +00:00
|
|
|
((GetOpCodeNumInsArray(1)[1] > 0) && (GetOpCodeNumInsArray(1)[2] == 0) &&
|
|
|
|
(GetOpCodeNumInsArray(1)[3] == 0)));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsSchedulable() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ != OpCode::NOP) && (!IsProlog()) && (!IsRoot()) && (!IsFixed()) &&
|
|
|
|
(GetOpCodeNumInsArray(1)[0] == 0);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsState() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ != OpCode::NOP) && (!IsProlog()) && (!IsRoot()) && (!IsFixed()) &&
|
|
|
|
(GetOpCodeNumInsArray(1)[0] > 0);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsGeneralState() const
|
|
|
|
{
|
2021-12-30 17:38:35 +00:00
|
|
|
return ((op_ == OpCode::IF_TRUE) || (op_ == OpCode::IF_FALSE) || (op_ == OpCode::IF_SUCCESS) ||
|
|
|
|
(op_ == OpCode::IF_EXCEPTION) || (op_ == OpCode::SWITCH_CASE) ||
|
|
|
|
(op_ == OpCode::DEFAULT_CASE) || (op_ == OpCode::MERGE) || (op_ == OpCode::LOOP_BEGIN) ||
|
|
|
|
(op_ == OpCode::ORDINARY_BLOCK) || (op_ == OpCode::STATE_ENTRY));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsTerminalState() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return ((op_ == OpCode::RETURN) || (op_ == OpCode::THROW) || (op_ == OpCode::RETURN_VOID));
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsCFGMerge() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ == OpCode::MERGE) || (op_ == OpCode::LOOP_BEGIN);
|
2021-09-04 08:06:49 +00:00
|
|
|
}
|
2021-09-26 06:47:20 +00:00
|
|
|
|
|
|
|
bool OpCode::IsControlCase() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ == OpCode::IF_BRANCH) || (op_ == OpCode::SWITCH_BRANCH) || (op_ == OpCode::IF_TRUE) ||
|
2021-12-30 17:38:35 +00:00
|
|
|
(op_ == OpCode::IF_FALSE) || (op_ == OpCode::IF_SUCCESS) || (op_ == OpCode::IF_EXCEPTION) ||
|
|
|
|
(op_ == OpCode::SWITCH_CASE) || (op_ == OpCode::DEFAULT_CASE);
|
2021-09-26 06:47:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool OpCode::IsLoopHead() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ == OpCode::LOOP_BEGIN);
|
2021-09-26 06:47:20 +00:00
|
|
|
}
|
2021-10-28 07:06:25 +00:00
|
|
|
|
|
|
|
bool OpCode::IsNop() const
|
|
|
|
{
|
2021-12-17 09:18:10 +00:00
|
|
|
return (op_ == OpCode::NOP);
|
2021-10-28 07:06:25 +00:00
|
|
|
}
|
2022-01-04 11:30:40 +00:00
|
|
|
} // namespace panda::ecmascript::kungfu
|