| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "RuntimeByteCodePch.h"
- namespace Js
- {
- bool OpCodeUtil::IsPrefixOpcode(OpCode op)
- {
- return op <= OpCode::ExtendedLargeLayoutPrefix && op != OpCode::EndOfBlock;
- }
- void OpCodeUtil::ConvertOpToNonProfiled(OpCode& op)
- {
- if (IsProfiledCallOp(op) || IsProfiledCallOpWithICIndex(op))
- {
- op = ConvertProfiledCallOpToNonProfiled(op);
- }
- else if (IsProfiledReturnTypeCallOp(op))
- {
- op = ConvertProfiledReturnTypeCallOpToNonProfiled(op);
- }
- else
- {
- ConvertNonCallOpToNonProfiled(op);
- }
- }
- void OpCodeUtil::ConvertNonCallOpToProfiled(OpCode& op)
- {
- Assert(OpCodeAttr::HasProfiledOp(op));
- op += 1;
- Assert(OpCodeAttr::IsProfiledOp(op));
- }
- void OpCodeUtil::ConvertNonCallOpToProfiledWithICIndex(OpCode& op)
- {
- Assert(OpCodeAttr::HasProfiledOp(op) && OpCodeAttr::HasProfiledOpWithICIndex(op));
- op += 2;
- Assert(OpCodeAttr::IsProfiledOpWithICIndex(op));
- }
- void OpCodeUtil::ConvertNonCallOpToNonProfiled(OpCode& op)
- {
- if (OpCodeAttr::IsProfiledOp(op))
- {
- op -= 1;
- Assert(OpCodeAttr::HasProfiledOp(op));
- }
- else if (OpCodeAttr::IsProfiledOpWithICIndex(op))
- {
- op -= 2;
- Assert(OpCodeAttr::HasProfiledOpWithICIndex(op));
- }
- else
- {
- Assert(false);
- }
- }
- bool OpCodeUtil::IsCallOp(OpCode op)
- {
- return op >= Js::OpCode::CallI && op <= Js::OpCode::CallIExtendedFlags;
- }
- bool OpCodeUtil::IsProfiledCallOp(OpCode op)
- {
- return op >= Js::OpCode::ProfiledCallI && op <= Js::OpCode::ProfiledCallIExtendedFlags;
- }
- bool OpCodeUtil::IsProfiledCallOpWithICIndex(OpCode op)
- {
- return op >= Js::OpCode::ProfiledCallIWithICIndex && op <= Js::OpCode::ProfiledCallIExtendedFlagsWithICIndex;
- }
- bool OpCodeUtil::IsProfiledConstructorCall(OpCode op)
- {
- return ((op >= Js::OpCode::NewScObject && op <= Js::OpCode::ProfiledNewScObjArraySpread) || op == Js::OpCode::ProfiledNewScObjectSpread) && (OpCodeAttr::IsProfiledOp(op) || OpCodeAttr::IsProfiledOpWithICIndex(op));
- }
- bool OpCodeUtil::IsProfiledReturnTypeCallOp(OpCode op)
- {
- return op >= Js::OpCode::ProfiledReturnTypeCallI && op <= Js::OpCode::ProfiledReturnTypeCallIExtendedFlags;
- }
- #if DBG
- OpCode OpCodeUtil::DebugConvertProfiledCallToNonProfiled(OpCode op)
- {
- switch (op)
- {
- case Js::OpCode::ProfiledCallI:
- case Js::OpCode::ProfiledCallIWithICIndex:
- return Js::OpCode::CallI;
- case Js::OpCode::ProfiledCallIFlags:
- case Js::OpCode::ProfiledCallIFlagsWithICIndex:
- return Js::OpCode::CallIFlags;
- case Js::OpCode::ProfiledCallIExtendedFlags:
- case Js::OpCode::ProfiledCallIExtendedFlagsWithICIndex:
- return Js::OpCode::CallIExtendedFlags;
- case Js::OpCode::ProfiledCallIExtended:
- case Js::OpCode::ProfiledCallIExtendedWithICIndex:
- return Js::OpCode::CallIExtended;
- default:
- Assert(false);
- };
- return Js::OpCode::Nop;
- }
- OpCode OpCodeUtil::DebugConvertProfiledReturnTypeCallToNonProfiled(OpCode op)
- {
- switch (op)
- {
- case Js::OpCode::ProfiledReturnTypeCallI:
- return Js::OpCode::CallI;
- case Js::OpCode::ProfiledReturnTypeCallIFlags:
- return Js::OpCode::CallIFlags;
- case Js::OpCode::ProfiledReturnTypeCallIExtendedFlags:
- return Js::OpCode::CallIExtendedFlags;
- case Js::OpCode::ProfiledReturnTypeCallIExtended:
- return Js::OpCode::CallIExtended;
- default:
- Assert(false);
- };
- return Js::OpCode::Nop;
- }
- #endif
- OpCode OpCodeUtil::ConvertProfiledCallOpToNonProfiled(OpCode op)
- {
- OpCode newOpcode = Js::OpCode::InvalidOpCode;
- if (IsProfiledCallOp(op))
- {
- newOpcode = (OpCode)(op - Js::OpCode::ProfiledCallI + Js::OpCode::CallI);
- }
- else if (IsProfiledCallOpWithICIndex(op))
- {
- newOpcode = (OpCode)(op - Js::OpCode::ProfiledCallIWithICIndex + Js::OpCode::CallI);
- }
- else
- {
- Assert(false);
- __assume(false);
- }
- Assert(DebugConvertProfiledCallToNonProfiled(op) == newOpcode);
- return newOpcode;
- }
- OpCode OpCodeUtil::ConvertProfiledReturnTypeCallOpToNonProfiled(OpCode op)
- {
- OpCode newOpcode = Js::OpCode::InvalidOpCode;
- if (IsProfiledReturnTypeCallOp(op))
- {
- newOpcode = (OpCode)(op - Js::OpCode::ProfiledReturnTypeCallI + Js::OpCode::CallI);
- }
- else
- {
- Assert(false);
- __assume(false);
- }
- Assert(DebugConvertProfiledReturnTypeCallToNonProfiled(op) == newOpcode);
- return newOpcode;
- }
- OpCode OpCodeUtil::ConvertCallOpToProfiled(OpCode op, bool withICIndex)
- {
- return (!withICIndex) ?
- (OpCode)(op - OpCode::CallI + OpCode::ProfiledCallI) :
- (OpCode)(op - OpCode::CallI + OpCode::ProfiledCallIWithICIndex);
- }
- OpCode OpCodeUtil::ConvertCallOpToProfiledReturnType(OpCode op)
- {
- return (OpCode)(op - OpCode::CallI + OpCode::ProfiledReturnTypeCallI);
- }
- CompileAssert(((int)Js::OpCode::CallIExtendedFlags - (int)Js::OpCode::CallI) == ((int)Js::OpCode::ProfiledCallIExtendedFlags - (int)Js::OpCode::ProfiledCallI));
- CompileAssert(((int)Js::OpCode::CallIExtendedFlags - (int)Js::OpCode::CallI) == ((int)Js::OpCode::ProfiledReturnTypeCallIExtendedFlags - (int)Js::OpCode::ProfiledReturnTypeCallI));
- CompileAssert(((int)Js::OpCode::CallIExtendedFlags - (int)Js::OpCode::CallI) == ((int)Js::OpCode::ProfiledCallIExtendedFlagsWithICIndex - (int)Js::OpCode::ProfiledCallIWithICIndex));
- // Only include the opcode name on debug and test build
- #if DBG_DUMP || ENABLE_DEBUG_CONFIG_OPTIONS
- char16 const * const OpCodeUtil::OpCodeNames[] =
- {
- #define DEF_OP(x, y, ...) _u("") STRINGIZEW(x) _u(""),
- #include "OpCodeList.h"
- #undef DEF_OP
- };
- char16 const * const OpCodeUtil::ExtendedOpCodeNames[] =
- {
- #define DEF_OP(x, y, ...) _u("") STRINGIZEW(x) _u(""),
- #include "ExtendedOpCodeList.h"
- #undef DEF_OP
- };
- char16 const * const OpCodeUtil::BackendOpCodeNames[] =
- {
- #define DEF_OP(x, y, ...) _u("") STRINGIZEW(x) _u(""),
- #include "BackendOpCodeList.h"
- #undef DEF_OP
- };
- char16 const * OpCodeUtil::GetOpCodeName(OpCode op)
- {
- if (op <= Js::OpCode::MaxByteSizedOpcodes)
- {
- Assert((uint)op < _countof(OpCodeNames));
- __analysis_assume((uint)op < _countof(OpCodeNames));
- return OpCodeNames[(uint)op];
- }
- else if (op < Js::OpCode::ByteCodeLast)
- {
- uint opIndex = op - (Js::OpCode::MaxByteSizedOpcodes + 1);
- Assert(opIndex < _countof(ExtendedOpCodeNames));
- __analysis_assume(opIndex < _countof(ExtendedOpCodeNames));
- return ExtendedOpCodeNames[opIndex];
- }
- uint opIndex = op - (Js::OpCode::ByteCodeLast + 1);
- Assert(opIndex < _countof(BackendOpCodeNames));
- __analysis_assume(opIndex < _countof(BackendOpCodeNames));
- return BackendOpCodeNames[opIndex];
- }
- #else
- wchar const * OpCodeUtil::GetOpCodeName(OpCode op)
- {
- return _u("<NotAvail>");
- }
- #endif
- OpLayoutType const OpCodeUtil::OpCodeLayouts[] =
- {
- #define DEF_OP(x, y, ...) OpLayoutType::y,
- #include "OpCodeList.h"
- };
- OpLayoutType const OpCodeUtil::ExtendedOpCodeLayouts[] =
- {
- #define DEF_OP(x, y, ...) OpLayoutType::y,
- #include "ExtendedOpCodeList.h"
- };
- OpLayoutType const OpCodeUtil::BackendOpCodeLayouts[] =
- {
- #define DEF_OP(x, y, ...) OpLayoutType::y,
- #include "BackendOpCodeList.h"
- };
- OpLayoutType OpCodeUtil::GetOpCodeLayout(OpCode op)
- {
- if ((uint)op <= (uint)Js::OpCode::MaxByteSizedOpcodes)
- {
- AnalysisAssert((uint)op < _countof(OpCodeLayouts));
- return OpCodeLayouts[(uint)op];
- }
- else if (op < Js::OpCode::ByteCodeLast)
- {
- uint opIndex = op - (Js::OpCode::MaxByteSizedOpcodes + 1);
- AnalysisAssert(opIndex < _countof(ExtendedOpCodeLayouts));
- return ExtendedOpCodeLayouts[opIndex];
- }
- uint opIndex = op - (Js::OpCode::ByteCodeLast + 1);
- AnalysisAssert(opIndex < _countof(BackendOpCodeLayouts));
- return BackendOpCodeLayouts[opIndex];
- }
- bool OpCodeUtil::IsValidByteCodeOpcode(OpCode op)
- {
- CompileAssert((int)Js::OpCode::MaxByteSizedOpcodes + 1 + _countof(OpCodeUtil::ExtendedOpCodeLayouts) == (int)Js::OpCode::ByteCodeLast);
- return (uint)op < _countof(OpCodeLayouts)
- || (op > Js::OpCode::MaxByteSizedOpcodes && op < Js::OpCode::ByteCodeLast);
- }
- bool OpCodeUtil::IsValidOpcode(OpCode op)
- {
- return IsValidByteCodeOpcode(op)
- || (op > Js::OpCode::ByteCodeLast && op < Js::OpCode::Count);
- }
- };
|