theweipeng commented on PR #1675:
URL: https://github.com/apache/fury/pull/1675#issuecomment-2205736393
> Hi, @theweipeng , Please have a look at my PR. I have been trying to
adjust the object.test.ts files so as to pass the pipline tests but i really
don't know the `writeStmt` and `readStmt` functions are tested in the
objects.test.ts files. Please help me with a few hints.
First, let me explain why we need to generate code, which is necessary for a
general understanding.
Without generating code for each object type, the JavaScript would look like
this:
```JavaScript
function writeObject(input, writer, description) {
description.fields.forEach(field => {
const binary = metaString.encode(field.name);
writer.write(binary);
});
description.fields.forEach(field => {
writeXxxx(input[field.name], writer, field.description);
});
}
```
In this pseudo-code, the function writeObject calls metaString.encode every
time and iterating over description.fields is unnecessary. Performance is very
important for Fury.
If we generate code for each object type, the JavaScript will look like this:
```JavaScript
const metaBinary = description.fields.map(field =>
metaString.encode(field.name)).join(/* code to join the binary data */);
function writeObject(input, writer) {
writer.write(metaBinary);
writeString(input.b);
writeBoolean(input.c);
}
```
In this pseudo-code, metaBinary is called only once when writeObject is
created, and we can avoid all overhead except for the necessary write buffer.
writeStmt is used to generate a code fragment that will be embedded by the
function toSerializer, declared in BaseSerializerGenerator.
For example, a description like the one below will generate code when
registerSerializer is called:
```JavaScript
const description = Type.object('example.foo', {
b: Type.string(),
c: Type.bool()
});
const fury = new Fury({ refTracking: true });
const serializer = fury.registerSerializer(description).serializer;
```
The call chain will be generateSerializer(gen/index.ts) ->
generate(gen/index.ts) -> generator.toSerializer(gen/index.ts) ->
toSerializer(gen/serializer.ts) -> writeStmt(gen/object.ts). `funcString`
declared in generate(gen/index.ts) store the final code.
writeStmt iterates through the properties defined in the description (in the
example, they are b and c) and generates the code based on the property's
description.
In this example, prop b will call writeStmt declared in gen/string.ts.
You can add a script for debugging like this:
https://github.com/apache/fury/assets/16490211/2c1f7b34-a4bd-4774-bc26-556b80a89c02
And click Debug:
https://github.com/apache/fury/assets/16490211/77d67ae8-042a-4ae1-b878-9de39777fb49
The test will pause at the breakpoint, allowing you to trace the call chain
by debugging the code generator.
In your case, you should create a write instance for meta inside a closure,
thus allowing direct writing of the meta binary.
For instance:
```JavaScript
const metaBinary = this.scope.declare("metaBinary",
`${metaString.encode(JSON.stringify(description))}`); // This line declares a
variable inside a closure.
return `
${this.builder.writer.binary(metaBinary)};
`;
```
tagWriter is in a similar situation; this should be helpful to you:
https://github.com/apache/fury/assets/16490211/401e9f36-09c6-4204-9102-b115fac9631a
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]