Skip to content

Commit

Permalink
Inline tag values in generated checks
Browse files Browse the repository at this point in the history
  • Loading branch information
DZakh committed Jul 13, 2024
1 parent 17fe6eb commit a5985b6
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 37 deletions.
2 changes: 1 addition & 1 deletion packages/tests/src/core/S_object_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ module Compiled = {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{if(i["zoo"]!==e[0]){e[1](i["zoo"])}return {"tag":e[2],"FOO":i["foo"],"BAR":i["bar"],}}`,
`i=>{if(i["zoo"]!==1){e[0](i["zoo"])}return {"tag":e[1],"FOO":i["foo"],"BAR":i["bar"],}}`,
)
},
)
Expand Down
4 changes: 2 additions & 2 deletions packages/tests/src/core/S_tuple_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ module Compiled = {
let schema = S.tuple(_ => ())

// TODO: No need to do unit check ?
t->U.assertCompiledCode(~schema, ~op=#Serialize, `i=>{if(i!==e[0]){e[1](i)}return []}`)
t->U.assertCompiledCode(~schema, ~op=#Serialize, `i=>{if(i!==undefined){e[0](i)}return []}`)
})

test(
Expand Down Expand Up @@ -305,7 +305,7 @@ module Compiled = {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{if(i["zoo"]!==e[0]){e[1](i["zoo"])}return [e[2],i["foo"],i["bar"],]}`,
`i=>{if(i["zoo"]!==1){e[0](i["zoo"])}return [e[1],i["foo"],i["bar"],]}`,
)
},
)
Expand Down
6 changes: 3 additions & 3 deletions packages/tests/src/core/S_union_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ module Advanced = {
t->U.assertCompiledCode(
~schema=shapeSchema,
~op=#Serialize,
`i=>{let v0,v1,v2,v3;try{if(i["TAG"]!==e[0]){e[1](i["TAG"])}v0={"kind":e[2],"radius":i["radius"],};if(!v0||v0.constructor!==Object){e[3](v0)}v1=v0}catch(e0){try{if(i["TAG"]!==e[4]){e[5](i["TAG"])}v2={"kind":e[6],"x":i["x"],};if(!v2||v2.constructor!==Object){e[7](v2)}v1=v2}catch(e1){try{if(i["TAG"]!==e[8]){e[9](i["TAG"])}v3={"kind":e[10],"x":i["x"],"y":i["y"],};if(!v3||v3.constructor!==Object){e[11](v3)}v1=v3}catch(e2){e[12]([e0,e1,e2,])}}}return v1}`,
`i=>{let v0,v1,v2,v3;try{if(i["TAG"]!=="Circle"){e[0](i["TAG"])}v0={"kind":e[1],"radius":i["radius"],};if(!v0||v0.constructor!==Object){e[2](v0)}v1=v0}catch(e0){try{if(i["TAG"]!=="Square"){e[3](i["TAG"])}v2={"kind":e[4],"x":i["x"],};if(!v2||v2.constructor!==Object){e[5](v2)}v1=v2}catch(e1){try{if(i["TAG"]!=="Triangle"){e[6](i["TAG"])}v3={"kind":e[7],"x":i["x"],"y":i["y"],};if(!v3||v3.constructor!==Object){e[8](v3)}v1=v3}catch(e2){e[9]([e0,e1,e2,])}}}return v1}`,
)
})
}
Expand Down Expand Up @@ -508,7 +508,7 @@ module CknittelBugReport = {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{let v2,v3,v6;try{let v0=i["_0"]["payload"]["a"],v1;if(i["TAG"]!==e[0]){e[1](i["TAG"])}if(v0!==void 0){v1=e[2](v0)}v2={"payload":{"a":v1,},};if(!v2||v2.constructor!==Object){e[3](v2)}v3=v2}catch(e0){try{let v4=i["_0"]["payload"]["b"],v5;if(i["TAG"]!==e[4]){e[5](i["TAG"])}if(v4!==void 0){v5=e[6](v4)}v6={"payload":{"b":v5,},};if(!v6||v6.constructor!==Object){e[7](v6)}v3=v6}catch(e1){e[8]([e0,e1,])}}return v3}`,
`i=>{let v2,v3,v6;try{let v0=i["_0"]["payload"]["a"],v1;if(i["TAG"]!=="A"){e[0](i["TAG"])}if(v0!==void 0){v1=e[1](v0)}v2={"payload":{"a":v1,},};if(!v2||v2.constructor!==Object){e[2](v2)}v3=v2}catch(e0){try{let v4=i["_0"]["payload"]["b"],v5;if(i["TAG"]!=="B"){e[3](i["TAG"])}if(v4!==void 0){v5=e[4](v4)}v6={"payload":{"b":v5,},};if(!v6||v6.constructor!==Object){e[5](v6)}v3=v6}catch(e1){e[6]([e0,e1,])}}return v3}`,
)

let x = {
Expand Down Expand Up @@ -605,7 +605,7 @@ module CrazyUnion = {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{let r0=i=>{let v5,v6,v12;try{let v0=i["_0"],v4=[];if(i["TAG"]!==e[0]){e[1](i["TAG"])}for(let v1=0;v1<v0.length;++v1){let v3;try{v3=r0(v0[v1])}catch(v2){if(v2&&v2.s===s){v2.path="[\\"_0\\"]"+\'["\'+v1+\'"]\'+v2.path}throw v2}v4.push(v3)}v5={"type":e[2],"nested":v4,};if(!v5||v5.constructor!==Object){e[3](v5)}v6=v5}catch(e0){try{if(i!=="B"){e[4](i)}if(i!=="B"){e[5](i)}v6=i}catch(e1){try{if(i!=="C"){e[6](i)}if(i!=="C"){e[7](i)}v6=i}catch(e2){try{if(i!=="D"){e[8](i)}if(i!=="D"){e[9](i)}v6=i}catch(e3){try{if(i!=="E"){e[10](i)}if(i!=="E"){e[11](i)}v6=i}catch(e4){try{if(i!=="F"){e[12](i)}if(i!=="F"){e[13](i)}v6=i}catch(e5){try{if(i!=="G"){e[14](i)}if(i!=="G"){e[15](i)}v6=i}catch(e6){try{if(i!=="H"){e[16](i)}if(i!=="H"){e[17](i)}v6=i}catch(e7){try{if(i!=="I"){e[18](i)}if(i!=="I"){e[19](i)}v6=i}catch(e8){try{if(i!=="J"){e[20](i)}if(i!=="J"){e[21](i)}v6=i}catch(e9){try{if(i!=="K"){e[22](i)}if(i!=="K"){e[23](i)}v6=i}catch(e10){try{if(i!=="L"){e[24](i)}if(i!=="L"){e[25](i)}v6=i}catch(e11){try{if(i!=="M"){e[26](i)}if(i!=="M"){e[27](i)}v6=i}catch(e12){try{if(i!=="N"){e[28](i)}if(i!=="N"){e[29](i)}v6=i}catch(e13){try{if(i!=="O"){e[30](i)}if(i!=="O"){e[31](i)}v6=i}catch(e14){try{if(i!=="P"){e[32](i)}if(i!=="P"){e[33](i)}v6=i}catch(e15){try{if(i!=="Q"){e[34](i)}if(i!=="Q"){e[35](i)}v6=i}catch(e16){try{if(i!=="R"){e[36](i)}if(i!=="R"){e[37](i)}v6=i}catch(e17){try{if(i!=="S"){e[38](i)}if(i!=="S"){e[39](i)}v6=i}catch(e18){try{if(i!=="T"){e[40](i)}if(i!=="T"){e[41](i)}v6=i}catch(e19){try{if(i!=="U"){e[42](i)}if(i!=="U"){e[43](i)}v6=i}catch(e20){try{if(i!=="V"){e[44](i)}if(i!=="V"){e[45](i)}v6=i}catch(e21){try{if(i!=="W"){e[46](i)}if(i!=="W"){e[47](i)}v6=i}catch(e22){try{if(i!=="X"){e[48](i)}if(i!=="X"){e[49](i)}v6=i}catch(e23){try{if(i!=="Y"){e[50](i)}if(i!=="Y"){e[51](i)}v6=i}catch(e24){try{let v7=i["_0"],v11=[];if(i["TAG"]!==e[52]){e[53](i["TAG"])}for(let v8=0;v8<v7.length;++v8){let v10;try{v10=r0(v7[v8])}catch(v9){if(v9&&v9.s===s){v9.path="[\\"_0\\"]"+\'["\'+v8+\'"]\'+v9.path}throw v9}v11.push(v10)}v12={"type":e[54],"nested":v11,};if(!v12||v12.constructor!==Object){e[55](v12)}v6=v12}catch(e25){e[56]([e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,])}}}}}}}}}}}}}}}}}}}}}}}}}}return v6};return r0(i)}`,
`i=>{let r0=i=>{let v5,v6,v12;try{let v0=i["_0"],v4=[];if(i["TAG"]!=="A"){e[0](i["TAG"])}for(let v1=0;v1<v0.length;++v1){let v3;try{v3=r0(v0[v1])}catch(v2){if(v2&&v2.s===s){v2.path="[\\"_0\\"]"+\'["\'+v1+\'"]\'+v2.path}throw v2}v4.push(v3)}v5={"type":e[1],"nested":v4,};if(!v5||v5.constructor!==Object){e[2](v5)}v6=v5}catch(e0){try{if(i!=="B"){e[3](i)}if(i!=="B"){e[4](i)}v6=i}catch(e1){try{if(i!=="C"){e[5](i)}if(i!=="C"){e[6](i)}v6=i}catch(e2){try{if(i!=="D"){e[7](i)}if(i!=="D"){e[8](i)}v6=i}catch(e3){try{if(i!=="E"){e[9](i)}if(i!=="E"){e[10](i)}v6=i}catch(e4){try{if(i!=="F"){e[11](i)}if(i!=="F"){e[12](i)}v6=i}catch(e5){try{if(i!=="G"){e[13](i)}if(i!=="G"){e[14](i)}v6=i}catch(e6){try{if(i!=="H"){e[15](i)}if(i!=="H"){e[16](i)}v6=i}catch(e7){try{if(i!=="I"){e[17](i)}if(i!=="I"){e[18](i)}v6=i}catch(e8){try{if(i!=="J"){e[19](i)}if(i!=="J"){e[20](i)}v6=i}catch(e9){try{if(i!=="K"){e[21](i)}if(i!=="K"){e[22](i)}v6=i}catch(e10){try{if(i!=="L"){e[23](i)}if(i!=="L"){e[24](i)}v6=i}catch(e11){try{if(i!=="M"){e[25](i)}if(i!=="M"){e[26](i)}v6=i}catch(e12){try{if(i!=="N"){e[27](i)}if(i!=="N"){e[28](i)}v6=i}catch(e13){try{if(i!=="O"){e[29](i)}if(i!=="O"){e[30](i)}v6=i}catch(e14){try{if(i!=="P"){e[31](i)}if(i!=="P"){e[32](i)}v6=i}catch(e15){try{if(i!=="Q"){e[33](i)}if(i!=="Q"){e[34](i)}v6=i}catch(e16){try{if(i!=="R"){e[35](i)}if(i!=="R"){e[36](i)}v6=i}catch(e17){try{if(i!=="S"){e[37](i)}if(i!=="S"){e[38](i)}v6=i}catch(e18){try{if(i!=="T"){e[39](i)}if(i!=="T"){e[40](i)}v6=i}catch(e19){try{if(i!=="U"){e[41](i)}if(i!=="U"){e[42](i)}v6=i}catch(e20){try{if(i!=="V"){e[43](i)}if(i!=="V"){e[44](i)}v6=i}catch(e21){try{if(i!=="W"){e[45](i)}if(i!=="W"){e[46](i)}v6=i}catch(e22){try{if(i!=="X"){e[47](i)}if(i!=="X"){e[48](i)}v6=i}catch(e23){try{if(i!=="Y"){e[49](i)}if(i!=="Y"){e[50](i)}v6=i}catch(e24){try{let v7=i["_0"],v11=[];if(i["TAG"]!=="Z"){e[51](i["TAG"])}for(let v8=0;v8<v7.length;++v8){let v10;try{v10=r0(v7[v8])}catch(v9){if(v9&&v9.s===s){v9.path="[\\"_0\\"]"+\'["\'+v8+\'"]\'+v9.path}throw v9}v11.push(v10)}v12={"type":e[52],"nested":v11,};if(!v12||v12.constructor!==Object){e[53](v12)}v6=v12}catch(e25){e[54]([e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,])}}}}}}}}}}}}}}}}}}}}}}}}}}return v6};return r0(i)}`,
)
})
}
6 changes: 3 additions & 3 deletions packages/tests/src/core/S_variant_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ test("Compiled code snapshot of variant applied to object", t => {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{if(i["TAG"]!==e[0]){e[1](i["TAG"])}return {"foo":i["_0"],}}`,
`i=>{if(i["TAG"]!=="Ok"){e[0](i["TAG"])}return {"foo":i["_0"],}}`,
)
})

Expand Down Expand Up @@ -161,7 +161,7 @@ test("Compiled serialize code snapshot", t => {
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{let v0=i["TAG"];if(v0!==e[0]){e[1](v0)}return i["_0"]}`,
`i=>{let v0=i["TAG"];if(v0!=="Ok"){e[0](v0)}return i["_0"]}`,
)
})

Expand All @@ -180,7 +180,7 @@ test(
t->U.assertCompiledCode(
~schema,
~op=#Serialize,
`i=>{let v0=e[2];if(i!==e[0]){e[1](i)}if(v0!==e[3]&&(!Array.isArray(v0)||v0.length!==2||v0[0]!==true||v0[1]!==12)){e[4](v0)}return v0}`,
`i=>{let v0=e[1];if(i!=="foo"){e[0](i)}if(v0!==e[2]&&(!Array.isArray(v0)||v0.length!==2||v0[0]!==true||v0[1]!==12)){e[3](v0)}return v0}`,
)
},
)
Expand Down
22 changes: 11 additions & 11 deletions src/S_Core.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,13 +1426,13 @@ function serializeOperationBuilder$1(b, input, selfSchema, path) {
}
return ;
}
var schema$1 = literal(definition);
var tagSchema = literal(definition);
var itemInputVar = inputVar + outputPath;
ctx.d = ctx.d + ("if(" + itemInputVar + "!==" + ("e[" + (b.g.e.push(definition) - 1) + "]") + "){" + failWithArg(b, path + outputPath, (function (input) {
ctx.d = ctx.d + ("if(" + tagSchema.f(b, itemInputVar) + "){" + failWithArg(b, path + outputPath, (function (received) {
return {
TAG: "InvalidType",
expected: schema$1,
received: input
expected: tagSchema,
received: received
};
}), itemInputVar) + "}");
};
Expand Down Expand Up @@ -1642,16 +1642,16 @@ function factory$3(schema, definer) {
}
return maybeOutputRef;
}
var schema = literal(definition);
var constantVal = valuePath === "" ? input : val(b, inputVar + valuePath);
var constantVar = $$var(b, constantVal);
b.c = b.c + ("if(" + constantVar + "!==" + ("e[" + (b.g.e.push(definition) - 1) + "]") + "){" + failWithArg(b, path + valuePath, (function (input) {
var tagSchema = literal(definition);
var tagVal = valuePath === "" ? input : val(b, inputVar + valuePath);
var tagInputVar = $$var(b, tagVal);
b.c = b.c + ("if(" + tagSchema.f(b, tagInputVar) + "){" + failWithArg(b, path + valuePath, (function (received) {
return {
TAG: "InvalidType",
expected: schema,
received: input
expected: tagSchema,
received: received
};
}), constantVar) + "}");
}), tagInputVar) + "}");
return 0;
};
var output = definitionToValue(definition, "");
Expand Down
42 changes: 25 additions & 17 deletions src/S_Core.res
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ module Obj = {
}

module Stdlib = {
module Option = {
external unsafeUnwrap: option<'a> => 'a = "%identity"
}

module Type = {
type t = [#undefined | #object | #boolean | #number | #bigint | #string | #symbol | #function]

Expand Down Expand Up @@ -819,7 +823,6 @@ module Literal = {
@inline
let toString = literal => (literal->toInternal).string

// FIXME:
let arrayFilterBuilder = (b, ~inputVar, ~literal) => {
let items = (literal->toInternal).items->(Obj.magic: option<unknown> => array<internal>)

Expand All @@ -841,7 +844,6 @@ module Literal = {
: "") ++ ")"
}

// FIXME:
let dictFilterBuilder = (b, ~inputVar, ~literal) => {
let items = (literal->toInternal).items->(Obj.magic: option<unknown> => dict<internal>)
let fields = items->Js.Dict.keys
Expand Down Expand Up @@ -2072,16 +2074,19 @@ module Object = {
}
}
} else {
let value = definition->Definition.toConstant
let schema = literal(value) // FIXME: Use it more actively
let tag = definition->Definition.toConstant
let tagSchema = literal(tag)
let itemInputVar = `${inputVar}${outputPath}`
ctx.discriminantCode =
ctx.discriminantCode ++
`if(${itemInputVar}!==${b->B.embed(value)}){${b->B.failWithArg(
`if(${(tagSchema.maybeTypeFilter->Stdlib.Option.unsafeUnwrap)(
b,
~inputVar=itemInputVar,
)}){${b->B.failWithArg(
~path=path->Path.concat(outputPath),
input => InvalidType({
expected: schema,
received: input,
received => InvalidType({
expected: tagSchema,
received,
}),
itemInputVar,
)}}`
Expand Down Expand Up @@ -2356,19 +2361,22 @@ module Variant = {
}
maybeOutputRef.contents
} else {
let constant = definition->Definition.toConstant
let schema = literal(constant) // FIXME: Use it more actively
let constantVal = valuePath === "" ? input : b->B.val(`${inputVar}${valuePath}`)
let constantVar = b->B.Val.var(constantVal)
let tag = definition->Definition.toConstant
let tagSchema = literal(tag)
let tagVal = valuePath === "" ? input : b->B.val(`${inputVar}${valuePath}`)
let tagInputVar = b->B.Val.var(tagVal)
b.code =
b.code ++
`if(${constantVar}!==${b->B.embed(constant)}){${b->B.failWithArg(
`if(${(tagSchema.maybeTypeFilter->Stdlib.Option.unsafeUnwrap)(
b,
~inputVar=tagInputVar,
)}){${b->B.failWithArg(
~path=path->Path.concat(valuePath),
input => InvalidType({
expected: schema,
received: input,
received => InvalidType({
expected: tagSchema,
received,
}),
constantVar,
tagInputVar,
)}}`
Unregistered
}
Expand Down

2 comments on commit a5985b6

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: a5985b6 Previous: 06df40b Ratio
Parse string 820077996 ops/sec (±0.12%) 818372259 ops/sec (±0.13%) 1.00
Serialize string 820806826 ops/sec (±0.08%) 819110535 ops/sec (±0.05%) 1.00
Advanced object schema factory 463692 ops/sec (±0.20%) 449156 ops/sec (±0.56%) 0.97
Parse advanced object 57246096 ops/sec (±0.45%) 45100200 ops/sec (±0.16%) 0.79
Assert advanced object 173671640 ops/sec (±0.20%)
Create and parse advanced object 93849 ops/sec (±0.19%) 35041 ops/sec (±1.18%) 0.37
Parse advanced strict object 25456380 ops/sec (±0.27%) 22748126 ops/sec (±0.24%) 0.89
Assert advanced strict object 30747119 ops/sec (±0.28%)
Serialize advanced object 75886082 ops/sec (±1.55%) 806595235 ops/sec (±0.11%) 10.63

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: a5985b6 Previous: 06df40b Ratio
Serialize advanced object 75886082 ops/sec (±1.55%) 806595235 ops/sec (±0.11%) 10.63

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.