| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- // Turn this on to enable magic constants in byte code (useful for debugging)
- //#define BYTE_CODE_MAGIC_CONSTANTS
- #include "ByteCode/ByteCodeSerializeFlags.h"
- namespace Js
- {
- // Some things are obscured by xor. This helps catch cases in which, for example, indirect property ids
- // are mistakenly mixed with actual property IDs.
- #if DBG & VALIDATE_SERIALIZED_BYTECODE
- #define SERIALIZER_OBSCURE_PROPERTY_ID 0xdef00000
- #define SERIALIZER_OBSCURE_NONBUILTIN_PROPERTY_ID 0xdeb00000
- #define SERIALIZER_OBSCURE_LITERAL_OBJECT_ID 0xded00000
- #else
- #define SERIALIZER_OBSCURE_PROPERTY_ID 0x00000000
- #define SERIALIZER_OBSCURE_NONBUILTIN_PROPERTY_ID 0x00000000
- #define SERIALIZER_OBSCURE_LITERAL_OBJECT_ID 0x00000000
- #endif
- class ByteCodeBufferReader;
- enum SerializedAuxiliaryKind : byte
- {
- sakVarArrayIntCount = 1,
- sakVarArrayVarCount = 2,
- sakPropertyIdArray = 3,
- sakFuncInfoArray = 4,
- sakIntArray = 5,
- sakFloatArray = 6
- };
- // Tightly pack serialized structures
- #pragma pack(push, 1)
- // Describes the kind of auxiliary
- struct SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int auxMagic; // magicStartOfAux
- #endif
- uint offset;
- SerializedAuxiliaryKind kind;
- SerializedAuxiliary(uint offset, SerializedAuxiliaryKind kind);
- };
- // The in-memory layout of the serialized analog of VarArray
- struct SerializedVarArray : SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int magic; // magicStartOfAuxVarArray
- #endif
- int varCount;
- SerializedVarArray(uint offset, bool isVarCount, int varCount);
- };
- struct SerializedIntArray : SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int magic; // magicStartOfAuxIntArray
- #endif
- int intCount;
- SerializedIntArray(uint offset, int intCount);
- };
- struct SerializedFloatArray : SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int magic; // magicStartOfAuxFltArray
- #endif
- int floatCount;
- SerializedFloatArray(uint offset, int floatCount);
- };
- // The in-memory layout of the serialized analog of PropertyIdArray
- struct SerializedPropertyIdArray : SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int magic; // magicStartOfAuxPropIdArray
- #endif
- int propertyCount;
- byte extraSlots;
- bool hadDuplicates;
- bool has__proto__;
- SerializedPropertyIdArray(uint offset, int propertyCount, byte extraSlots, bool hadDuplicates, bool has__proto__);
- };
- // The in-memory layout of the serialized analog of FuncInfoArray
- struct SerializedFuncInfoArray : SerializedAuxiliary
- {
- #ifdef BYTE_CODE_MAGIC_CONSTANTS
- int magic; // magicStartOfAuxFuncInfoArray
- #endif
- int count;
- SerializedFuncInfoArray(uint offset, int count);
- };
- #pragma pack(pop)
- // Holds information about the deserialized bytecode cache. Contains fast inline functions
- // for the lookup hit case. The slower deserialization of VarArray, etc are in the .cpp.
- class ByteCodeCache
- {
- ByteCodeBufferReader * reader;
- const byte * raw;
- PropertyId * propertyIds;
- int propertyCount;
- int builtInPropertyCount;
- public:
- ByteCodeCache(ScriptContext * scriptContext, ByteCodeBufferReader * reader, int builtInPropertyCount);
- void PopulateLookupPropertyId(ScriptContext * scriptContext, int realArrayOffset);
- ByteCodeBufferReader* GetReader()
- {
- return reader;
- }
- // Convert a serialized propertyID into a real one.
- inline PropertyId LookupPropertyId(PropertyId obscuredIdInCache) const
- {
- auto unobscured = obscuredIdInCache ^ SERIALIZER_OBSCURE_PROPERTY_ID;
- if (unobscured < builtInPropertyCount || unobscured==/*nil*/0xffffffff)
- {
- return unobscured; // This is a built in property id
- }
- auto realOffset = unobscured - builtInPropertyCount;
- Assert(realOffset<propertyCount);
- Assert(propertyIds[realOffset]!=-1);
- return propertyIds[realOffset];
- }
- // Convert a serialized propertyID into a real one.
- inline PropertyId LookupNonBuiltinPropertyId(PropertyId obscuredIdInCache) const
- {
- auto realOffset = obscuredIdInCache ^ SERIALIZER_OBSCURE_NONBUILTIN_PROPERTY_ID;
- Assert(realOffset<propertyCount);
- Assert(propertyIds[realOffset]!=-1);
- return propertyIds[realOffset];
- }
- // Get the raw byte code buffer.
- inline const byte * GetBuffer() const
- {
- return raw;
- }
- };
- // Methods for serializing and deserializing function bodies.
- struct ByteCodeSerializer
- {
- // Serialize a function body.
- static HRESULT SerializeToBuffer(ScriptContext * scriptContext, ArenaAllocator * alloc, DWORD sourceCodeLength, LPCUTF8 utf8Source, FunctionBody * function, SRCINFO const* srcInfo, bool allocateBuffer, byte ** buffer, DWORD * bufferBytes, DWORD dwFlags = 0);
- // Deserialize a function body. The content of utf8Source must be the same as was originally passed to SerializeToBuffer
- static HRESULT DeserializeFromBuffer(ScriptContext * scriptContext, uint32 scriptFlags, LPCUTF8 utf8Source, SRCINFO const * srcInfo, byte * buffer, NativeModule *nativeModule, Field(FunctionBody*)* function, uint sourceIndex = Js::Constants::InvalidSourceIndex);
- static HRESULT DeserializeFromBuffer(ScriptContext * scriptContext, uint32 scriptFlags, ISourceHolder* sourceHolder, SRCINFO const * srcInfo, byte * buffer, NativeModule *nativeModule, Field(FunctionBody*)* function, uint sourceIndex = Js::Constants::InvalidSourceIndex);
- static FunctionBody* DeserializeFunction(ScriptContext* scriptContext, DeferDeserializeFunctionInfo* deferredFunction);
- // This lib doesn't directly depend on the generated interfaces. Ensure the same codes with a C_ASSERT
- static const HRESULT CantGenerate = 0x80020201L;
- static const HRESULT InvalidByteCode = 0x80020202L;
- static void ReadSourceInfo(const DeferDeserializeFunctionInfo* deferredFunction, int& lineNumber, int& columnNumber, bool& m_isEval, bool& m_isDynamicFunction);
- private:
- static HRESULT DeserializeFromBufferInternal(ScriptContext * scriptContext, uint32 scriptFlags, LPCUTF8 utf8Source, ISourceHolder* sourceHolder, SRCINFO const * srcInfo, byte * buffer, NativeModule *nativeModule, Field(FunctionBody*)* function, uint sourceIndex = Js::Constants::InvalidSourceIndex);
- };
- }
|