In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the relevant knowledge of "how to implement the HeadNumber class of js engine". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1 HeadNumber
The code for the HeadNumber class is relatively small.
/ / The HeapNumber class describes heap allocated numbers that cannot be
/ / represented in a Smi (small integer)
/ / A heap object with stored numbers
Class HeapNumber: public HeapObject {
Public:
/ / [value]: number value.
Inline double value ()
Inline void set_value (double value)
/ / Casting.
Static inline HeapNumber* cast (Object* obj)
/ / Dispatched behavior.
Object* HeapNumberToBoolean ()
/ / Layout description.
/ / the space before kSize stores pointers to map objects
Static const int kValueOffset = HeapObject::kSize
The value of the number stored between / / kValueOffset-kSize
Static const int kSize = kValueOffset + kDoubleSize
Private:
DISALLOW_IMPLICIT_CONSTRUCTORS (HeapNumber)
}
Let's take a look at his realization.
/ / read out the value of double type
# define READ_DOUBLE_FIELD (p, offset)\
(* reinterpret_cast (FIELD_ADDR (p, offset)
/ / write a value of type double
# define WRITE_DOUBLE_FIELD (p, offset, value)\
(* reinterpret_cast (FIELD_ADDR (p, offset)) = value)
/ / read-write attribute value
Double HeapNumber::value () {
Return READ_DOUBLE_FIELD (this, kValueOffset)
}
/ / write double value to object
Void HeapNumber::set_value (double value) {
WRITE_DOUBLE_FIELD (this, kValueOffset, value)
}
Object* HeapNumber::HeapNumberToBoolean () {
/ / NaN, + 0, and-0 should return the false object
Switch (fpclassify (value () {
Case FP_NAN: / / fall through
Case FP_ZERO: return Heap::false_value ()
Default: return Heap::true_value ()
}
}
Another function is cast, which is implemented as follows:
CAST_ACCESSOR (HeapNumber)
# define CAST_ACCESSOR (type)\
Type* type::cast (Object* object) {\
ASSERT (object- > Is##type ());
Return reinterpret_cast (object);\
CAST_ACCESSOR (HeapNumber)
After the macro unfolds
HeapNumber* HeapNumber::cast (Object* object) {\
ASSERT (object- > IsHeapNumber ());
Return reinterpret_cast (object);\
So far, the HeapNumber analysis is over. Move on to the next class, Array.
2 Array
/ / Abstract super class arrays. It provides length behavior.
Class Array: public HeapObject {
Public:
/ / [length]: length of the array.
Inline int length ()
Inline void set_length (int value)
/ / Convert an object to an array index.
/ / Returns true if the conversion succeeded.
Static inline bool IndexFromObject (Object* object, uint32_t* index)
/ / Layout descriptor.
Static const int kLengthOffset = HeapObject::kSize
Static const int kHeaderSize = kLengthOffset + kIntSize
Private:
DISALLOW_IMPLICIT_CONSTRUCTORS (Array)
}
We found that there is only one property in the object memory layout of the array. Is to save the size of length. Let's first look at the implementation of the read-write length property.
# define INT_ACCESSORS (holder, name, offset)\
Int holder::name () {return READ_INT_FIELD (this, offset);}\
Void holder::set_##name (int value) {WRITE_INT_FIELD (this, offset, value);}
/ / define the length and set_length functions of the array, with the attribute in the kLengthOffset of the offset of the object, followed by the map pointer
INT_ACCESSORS (Array, length, kLengthOffset)
Let's move on to the implementation of IndexFromObject.
Bool Array::IndexFromObject (Object* object, uint32_t* index) {
If (object- > IsSmi ()) {
Int value = Smi::cast (object)-> value ()
If (value
< 0) return false; *index = value; return true; } if (object->IsHeapNumber () {
Double value = HeapNumber::cast (object)-> value ()
Uint32_t uint_value = static_cast (value)
If (value = = static_cast (uint_value)) {
* index = uint_value
Return true
}
}
Return false
}
This function converts an object (which represents numbers at the bottom) into an array index. The array class is also analyzed. Let's move on.
3 ByteArray
/ / ByteArray represents fixed sized byte arrays. Used by the outside world
/ / such as PCRE, and also by the memory allocator and garbage collector to
/ / fill in free blocks in the heap.
Class ByteArray: public Array {
Public:
/ / Setter and getter.
Inline byte get (int index)
Inline void set (int index, byte value)
/ / Treat contents as an int array.
Inline int get_int (int index)
/ *
The ByteArray class does not define its own properties, it calculates the size of the object according to the length
Then, when allocating memory, allocate an extra piece of memory to store array elements.
Const int kObjectAlignmentBits = 2
Const int kObjectAlignmentMask = (1 = kHeaderSize)
Return size_in_bytes-kHeaderSize
}
/ / Returns data start address.
Inline Address GetDataStartAddress ()
/ / Returns a pointer to the ByteArray object for a given data start address.
Static inline ByteArray* FromDataStartAddress (Address address)
/ / Casting.
Static inline ByteArray* cast (Object* obj)
/ / Dispatched behavior.
Int ByteArraySize () {return SizeFor (length ());}
Private:
DISALLOW_IMPLICIT_CONSTRUCTORS (ByteArray)
}
Before analyzing the implementation, let's take a look at how ByteArray's objects are allocated.
Handle Factory::NewByteArray (int length) {
ASSERT (0 MaxHeapObjectSize ()? LO_SPACE: NEW_SPACE
Object* result = AllocateRaw (size, space)
If (result- > IsFailure ()) return result
Reinterpret_cast (result)-> set_map (byte_array_map ())
Reinterpret_cast (result)-> set_length (length)
Return result
}
We see that the first step is to calculate the memory size size required by the object through ByteArray::SizeFor. Then allocate a piece of memory with the size of size. Then return the address of this block of memory. At this point we can use this piece of memory. Let's see how it works. The memory layout is as follows.
Byte ByteArray::get (int index) {
ASSERT (index > = 0 & & index
< this->Length ()
/ / returns the value of the corresponding element in the array according to the index. KHeaderSize is the address of the first element, and kCharSize is 1, that is, one byte.
Return READ_BYTE_FIELD (this, kHeaderSize + index * kCharSize)
}
Void ByteArray::set (int index, byte value) {
ASSERT (index > = 0 & & index
< this->Length ()
WRITE_BYTE_FIELD (this, kHeaderSize + index * kCharSize, value)
}
/ / take the contents of four elements (four bytes) as a value. That is, ByteArray becomes IntArray.
Int ByteArray::get_int (int index) {
ASSERT (index > = 0 & & (index * kIntSize)
< this->Length ()
Return READ_INT_FIELD (this, kHeaderSize + index * kIntSize)
}
ByteArray* ByteArray::FromDataStartAddress (Address address) {
ASSERT_TAG_ALIGNED (address)
Return reinterpret_cast (address-kHeaderSize + kHeapObjectTag)
}
/ / returns the first address of the array element. The low bit of the address is used as a token and should be subtracted first. KHeaderSize is the offset of the first element in the object's memory space
Address ByteArray::GetDataStartAddress () {
/ *
Typedef uint8_t byte
Typedef byte* Address
, /
Return reinterpret_cast (this)-kHeapObjectTag + kHeaderSize
}
This is the end of the content of "how to implement the HeadNumber class of js engine". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.