温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

js引擎v8源码怎么解析map对象

发布时间:2021-12-09 09:28:01 阅读:186 作者:柒染 栏目:大数据
前端开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

js引擎v8源码怎么解析map对象,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

首先介绍Map类。下面先看类定义

   
     
 
    
    // All heap objects have a Map that describes their structure.//  A Map contains information about://  - Size information about the object//  - How to iterate over an object (for garbage collection)class Map: public HeapObject { public:  // instance size.  inline int instance_size();  inline void set_instance_size(int value);  // instance type.  inline InstanceType instance_type();  inline void set_instance_type(InstanceType value);  // tells how many unused property fields are available in the instance.  // (only used for JSObject in fast mode).  inline int unused_property_fields();  inline void set_unused_property_fields(int value);  // bit field.  inline byte bit_field();  inline void set_bit_field(byte value);  // Tells whether this object has a special lookup behavior.  void set_special_lookup() {    set_bit_field(bit_field() | (1 << kHasSpecialLookup));  }  bool has_special_lookup() {    return ((1 << kHasSpecialLookup) & bit_field()) != 0;  }  // Tells whether the object in the prototype property will be used  // for instances created from this function.  If the prototype  // property is set to a value that is not a JSObject, the prototype  // property will not be used to create instances of the function.  // See ECMA-262, 13.2.2.  inline void set_non_instance_prototype(bool value);  inline bool has_non_instance_prototype();  // Tells whether the instance with this map should be ignored by the  // __proto__ accessor.  inline void set_is_hidden_prototype() {    set_bit_field(bit_field() | (1 << kIsHiddenPrototype));  }  inline bool is_hidden_prototype() {    return ((1 << kIsHiddenPrototype) & bit_field()) != 0;  }  // Tells whether the instance has a named interceptor.  inline void set_has_named_interceptor() {    set_bit_field(bit_field() | (1 << kHasNamedInterceptor));  }  inline bool has_named_interceptor() {    return ((1 << kHasNamedInterceptor) & bit_field()) != 0;  }  // Tells whether the instance has a named interceptor.  inline void set_has_indexed_interceptor() {    set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));  }  inline bool has_indexed_interceptor() {    return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;  }  // Tells whether the instance is undetectable.  // An undetectable object is a special class of JSObject: 'typeof' operator  // returns undefined, ToBoolean returns false. Otherwise it behaves like  // a normal JS object.  It is useful for implementing undetectable  // document.all in Firefox & Safari.  // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.  inline void set_is_undetectable() {    set_bit_field(bit_field() | (1 << kIsUndetectable));  }  inline bool is_undetectable() {    return ((1 << kIsUndetectable) & bit_field()) != 0;  }  // Tells whether the instance has a call-as-function handler.  inline void set_has_instance_call_handler() {    set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));  }  inline bool has_instance_call_handler() {    return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;  }  // Tells whether the instance needs security checks when accessing its  // properties.  inline void set_needs_access_check() {    set_bit_field(bit_field() | (1 << kNeedsAccessCheck));  }  inline bool needs_access_check() {    return ((1 << kNeedsAccessCheck) & bit_field()) != 0;  }  // [prototype]: implicit prototype object.  /*        #define DECL_ACCESSORS(name, type)  \      inline type* name();                 \      inline void set_##name(type* value)      宏展开后变成,定义了读写某个属性的函数      Object * prototype();      void * set_prototype(Object * value);      属性的定义如下(宏展开后也是读写某个属性):        #define ACCESSORS(holder, name, type, offset)                                   \          type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \          void holder::set_##name(type* value) {                                \            WRITE_FIELD(this, offset, value);                                   \            WRITE_BARRIER(this, offset);                                        \          }        // 定义各个类的读写某属性的函数,第三第四个参数是类型和偏移        ACCESSORS(Map, instance_descriptors, DescriptorArray,                  kInstanceDescriptorsOffset)        ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)        ACCESSORS(Map, constructor, Object, kConstructorOffset  */  DECL_ACCESSORS(prototype, Object)  // [constructor]: points back to the function responsible for this map.  DECL_ACCESSORS(constructor, Object)  // [instance descriptors]: describes the object.  DECL_ACCESSORS(instance_descriptors, DescriptorArray)  // [stub cache]: contains stubs compiled for this map.  DECL_ACCESSORS(code_cache, FixedArray)  // Returns a copy of the map.  Object* Copy();  // Returns the property index for name (only valid for FAST MODE).  int PropertyIndexFor(String* name);  // Returns the next free property index (only valid for FAST MODE).  int NextFreePropertyIndex();  // Returns the number of properties described in instance_descriptors.  int NumberOfDescribedProperties();  // Casting.  static inline Map* cast(Object* obj);  // Locate an accessor in the instance descriptor.  AccessorDescriptor* FindAccessor(String* name);  // Make sure the instance descriptor has no map transitions  Object* EnsureNoMapTransitions();  // Code cache operations.  // Clears the code cache.  inline void ClearCodeCache();  // Update code cache.  Object* UpdateCodeCache(String* name, Code* code);  // Returns the found code or undefined if absent.  Object* FindInCodeCache(String* name, Code::Flags flags);  // Tells whether code is in the code cache.  bool IncludedInCodeCache(Code* code);  // Dispatched behavior.  void MapIterateBody(ObjectVisitor* v);#ifdef DEBUG  void MapPrint();  void MapVerify();#endif  // Layout description.  static const int kInstanceAttributesOffset = HeapObject::kSize;  static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;  static const int kConstructorOffset = kPrototypeOffset + kPointerSize;  static const int kInstanceDescriptorsOffset =      kConstructorOffset + kPointerSize;  static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize;  static const int kSize = kCodeCacheOffset + kIntSize;  // Byte offsets within kInstanceAttributesOffset attributes.  static const int kInstanceSizeOffset = kInstanceAttributesOffset + 0;  static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;  static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 2;  static const int kBitFieldOffset = kInstanceAttributesOffset + 3;  // kBitFieldOffset对应的一个字节,下面分别是该一个字节各比特位的标记  static const int kHasSpecialLookup = 0;  static const int kHasNonInstancePrototype = 1;  static const int kIsHiddenPrototype = 2;  static const int kHasNamedInterceptor = 3;  static const int kHasIndexedInterceptor = 4;  static const int kIsUndetectable = 5;  static const int kHasInstanceCallHandler = 6;  static const int kNeedsAccessCheck = 7; private:  DISALLOW_IMPLICIT_CONSTRUCTORS(Map);};
   
     
 
    
    AI代码助手复制代码

下面的map的属性内存布局。

js引擎v8源码怎么解析map对象

我们逐个函数分析他的实现。首先看objects-inl.h中的实现。

   
     
 
    
    // 获取对象某个属性的地址,p是对象的首地址,offset是偏移,kHeapObjectTag是对象的标记,算地址的时候需要减掉#define FIELD_ADDR(p, offset) \  (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)// 读写一个字节的内容#define READ_BYTE_FIELD(p, offset) \  (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))#define WRITE_BYTE_FIELD(p, offset, value) \  (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)void Map::set_instance_size(int value) {  ASSERT(0 <= value && value < 256);  WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));}InstanceType Map::instance_type() {  return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));}void Map::set_instance_type(InstanceType value) {  ASSERT(0 <= value && value < 256);  WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);}int Map::unused_property_fields() {  return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);}void Map::set_unused_property_fields(int value) {  WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));}// 读写一个字节的内容,每个比特都记录着一个标记byte Map::bit_field() {  return READ_BYTE_FIELD(this, kBitFieldOffset);}void Map::set_bit_field(byte value) {  WRITE_BYTE_FIELD(this, kBitFieldOffset, value);}void Map::set_non_instance_prototype(bool value) {  if (value) {    // 设置该位    set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));  } else {    // 清除该位    set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));  }}// 是否设置了某位bool Map::has_non_instance_prototype() {  return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;}void Map::ClearCodeCache() {  // No write barrier is needed since empty_fixed_array is not in new space.  // Please note this function is used during marking:  //  - MarkCompactCollector::MarkUnmarkedObject  ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));  WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());}
   
     
 
    
    AI代码助手复制代码

从上面的代码中我们知道,只是对某些属性或标记进行读写。

关于js引擎v8源码怎么解析map对象问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4217331/blog/4379423

AI

开发者交流群×