amis-rpc-design/node_modules/hermes-parser/dist/HermesParserDeserializer.js
2023-10-07 19:42:30 +08:00

243 lines
6.4 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @format
*/
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _HermesParserDecodeUTF8String = _interopRequireDefault(require("./HermesParserDecodeUTF8String"));
var _HermesParserNodeDeserializers = _interopRequireDefault(require("./HermesParserNodeDeserializers"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class HermesParserDeserializer {
// Matches StoredComment::Kind enum in JSLexer.h
// Matches TokenType enum in HermesParserJSSerializer.h
constructor(programBuffer, positionBuffer, positionBufferSize, wasmParser, options) {
this.programBufferIdx = void 0;
this.positionBufferIdx = void 0;
this.positionBufferSize = void 0;
this.locMap = void 0;
this.HEAPU8 = void 0;
this.HEAPU32 = void 0;
this.HEAPF64 = void 0;
this.options = void 0;
this.commentTypes = ['CommentLine', 'CommentBlock', 'InterpreterDirective'];
this.tokenTypes = ['Boolean', 'Identifier', 'Keyword', 'Null', 'Numeric', 'BigInt', 'Punctuator', 'String', 'RegularExpression', 'Template', 'JSXText'];
// Program and position buffer are memory addresses, so we must convert
// into indices into HEAPU32 (an array of 4-byte integers).
this.programBufferIdx = programBuffer / 4;
this.positionBufferIdx = positionBuffer / 4;
this.positionBufferSize = positionBufferSize;
this.locMap = {};
this.HEAPU8 = wasmParser.HEAPU8;
this.HEAPU32 = wasmParser.HEAPU32;
this.HEAPF64 = wasmParser.HEAPF64;
this.options = options;
}
/**
* Consume and return the next 4 bytes in the program buffer.
*/
next() {
const num = this.HEAPU32[this.programBufferIdx++];
return num;
}
deserialize() {
const program = {
type: 'Program',
loc: this.addEmptyLoc(),
body: this.deserializeNodeList(),
comments: this.deserializeComments()
};
if (this.options.tokens === true) {
program.tokens = this.deserializeTokens();
}
this.fillLocs();
return program;
}
/**
* Booleans are serialized as a single 4-byte integer.
*/
deserializeBoolean() {
return Boolean(this.next());
}
/**
* Numbers are serialized directly into program buffer, taking up 8 bytes
* preceded by 4 bytes of alignment padding if necessary.
*/
deserializeNumber() {
let floatIdx; // Numbers are aligned on 8-byte boundaries, so skip padding if we are at
// an odd index into the 4-byte aligned program buffer.
if (this.programBufferIdx % 2 === 0) {
floatIdx = this.programBufferIdx / 2;
this.programBufferIdx += 2;
} else {
floatIdx = (this.programBufferIdx + 1) / 2;
this.programBufferIdx += 3;
}
return this.HEAPF64[floatIdx];
}
/**
* Strings are serialized as a 4-byte pointer into the heap, followed
* by their size as a 4-byte integer. The size is only present if the
* pointer is non-null.
*/
deserializeString() {
const ptr = this.next();
if (ptr === 0) {
return null;
}
const size = this.next();
return (0, _HermesParserDecodeUTF8String.default)(ptr, size, this.HEAPU8);
}
/**
* Nodes are serialized as a 4-byte integer denoting their node kind,
* followed by a 4-byte loc ID, followed by serialized node properties.
*
* If the node kind is 0 the node is null, otherwise the node kind - 1 is an
* index into the array of node deserialization functions.
*/
deserializeNode() {
const nodeType = this.next();
if (nodeType === 0) {
return null;
}
const nodeDeserializer = _HermesParserNodeDeserializers.default[nodeType - 1].bind(this);
return nodeDeserializer();
}
/**
* Node lists are serialized as a 4-byte integer denoting the number of
* elements in the list, followed by the serialized elements.
*/
deserializeNodeList() {
const size = this.next();
const nodeList = [];
for (let i = 0; i < size; i++) {
nodeList.push(this.deserializeNode());
}
return nodeList;
}
/**
* Comments are serialized as a node list, where each comment is serialized
* as a 4-byte integer denoting comment type, followed by a 4-byte value
* denoting the loc ID, followed by a serialized string for the comment value.
*/
deserializeComments() {
const size = this.next();
const comments = [];
for (let i = 0; i < size; i++) {
const commentType = this.commentTypes[this.next()];
const loc = this.addEmptyLoc();
const value = this.deserializeString();
comments.push({
type: commentType,
loc,
value
});
}
return comments;
}
deserializeTokens() {
const size = this.next();
const tokens = [];
for (let i = 0; i < size; i++) {
const tokenType = this.tokenTypes[this.next()];
const loc = this.addEmptyLoc();
const value = this.deserializeString();
tokens.push({
type: tokenType,
loc,
value
});
}
return tokens;
}
/**
* While deserializing the AST locations are represented by
* a 4-byte loc ID. This is used to create a map of loc IDs to empty loc
* objects that are filled after the AST has been deserialized.
*/
addEmptyLoc() {
// $FlowExpectedError
const loc = {};
this.locMap[this.next()] = loc;
return loc;
}
/**
* Positions are serialized as a loc ID which denotes which loc it is associated with,
* followed by kind which denotes whether it is a start or end position,
* followed by line, column, and offset (4-bytes each).
*/
fillLocs() {
for (let i = 0; i < this.positionBufferSize; i++) {
const locId = this.HEAPU32[this.positionBufferIdx++];
const kind = this.HEAPU32[this.positionBufferIdx++];
const line = this.HEAPU32[this.positionBufferIdx++];
const column = this.HEAPU32[this.positionBufferIdx++];
const offset = this.HEAPU32[this.positionBufferIdx++];
const loc = this.locMap[locId];
if (kind === 0) {
loc.start = {
line,
column
};
loc.rangeStart = offset;
} else {
loc.end = {
line,
column
};
loc.rangeEnd = offset;
}
}
}
}
exports.default = HermesParserDeserializer;