Skip to content

Commit

Permalink
Reproduce the problem
Browse files Browse the repository at this point in the history
  • Loading branch information
DZakh committed Jul 12, 2024
1 parent 6f80856 commit e440b08
Show file tree
Hide file tree
Showing 7 changed files with 495 additions and 19 deletions.
89 changes: 82 additions & 7 deletions packages/tests/src/benchmark/Benchmark.bs.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Benchmark from "benchmark";
import * as Core__Array from "@rescript/core/src/Core__Array.bs.mjs";
import * as S$RescriptSchema from "rescript-schema/src/S.bs.mjs";

function addWithPrepare(suite, name, fn) {
Expand Down Expand Up @@ -74,47 +75,121 @@ S$RescriptSchema.setGlobalConfig({
disableNanNumberCheck: true
});

var schema = S$RescriptSchema.recursive(function (schema) {
return S$RescriptSchema.union([
S$RescriptSchema.object(function (s) {
s.tag("type", "A");
return {
TAG: "A",
_0: s.f("nested", S$RescriptSchema.array(schema))
};
}),
S$RescriptSchema.literal("B"),
S$RescriptSchema.literal("C"),
S$RescriptSchema.literal("D"),
S$RescriptSchema.literal("E"),
S$RescriptSchema.literal("F"),
S$RescriptSchema.literal("G"),
S$RescriptSchema.literal("H"),
S$RescriptSchema.literal("I"),
S$RescriptSchema.literal("J"),
S$RescriptSchema.literal("K"),
S$RescriptSchema.literal("L"),
S$RescriptSchema.literal("M"),
S$RescriptSchema.literal("N"),
S$RescriptSchema.literal("O"),
S$RescriptSchema.literal("P"),
S$RescriptSchema.literal("Q"),
S$RescriptSchema.literal("R"),
S$RescriptSchema.literal("S"),
S$RescriptSchema.literal("T"),
S$RescriptSchema.literal("U"),
S$RescriptSchema.literal("V"),
S$RescriptSchema.literal("W"),
S$RescriptSchema.literal("X"),
S$RescriptSchema.literal("Y"),
S$RescriptSchema.object(function (s) {
s.tag("type", "Z");
return {
TAG: "Z",
_0: s.f("nested", S$RescriptSchema.array(schema))
};
})
]);
});

var testData1 = {
TAG: "Z",
_0: Core__Array.make(2, {
TAG: "Z",
_0: Core__Array.make(2, {
TAG: "Z",
_0: Core__Array.make(2, "Y")
})
})
};

Core__Array.make(2, {
TAG: "A",
_0: Core__Array.make(2, {
TAG: "A",
_0: Core__Array.make(2, "B")
})
});

function test() {
console.time("testData1 serialize");
var json = S$RescriptSchema.serializeOrRaiseWith(testData1, schema);
console.timeEnd("testData1 serialize");
console.time("testData1 parse");
S$RescriptSchema.parseOrRaiseWith(json, schema);
console.timeEnd("testData1 parse");
console.log(schema.parseOrThrow.toString());
}

test();

var data = makeTestObject();

console.time("makeAdvancedObjectSchema");

var schema = makeAdvancedObjectSchema();
var schema$1 = makeAdvancedObjectSchema();

console.timeEnd("makeAdvancedObjectSchema");

console.time("parseAnyWith: 1");

S$RescriptSchema.parseAnyWith(data, schema);
S$RescriptSchema.parseAnyWith(data, schema$1);

console.timeEnd("parseAnyWith: 1");

console.time("parseAnyWith: 2");

S$RescriptSchema.parseAnyWith(data, schema);
S$RescriptSchema.parseAnyWith(data, schema$1);

console.timeEnd("parseAnyWith: 2");

console.time("parseAnyWith: 3");

S$RescriptSchema.parseAnyWith(data, schema);
S$RescriptSchema.parseAnyWith(data, schema$1);

console.timeEnd("parseAnyWith: 3");

console.time("serializeWith: 1");

S$RescriptSchema.serializeWith(data, schema);
S$RescriptSchema.serializeWith(data, schema$1);

console.timeEnd("serializeWith: 1");

console.time("serializeWith: 2");

S$RescriptSchema.serializeWith(data, schema);
S$RescriptSchema.serializeWith(data, schema$1);

console.timeEnd("serializeWith: 2");

console.time("serializeWith: 3");

S$RescriptSchema.serializeWith(data, schema);
S$RescriptSchema.serializeWith(data, schema$1);

console.timeEnd("serializeWith: 3");

Expand Down
98 changes: 98 additions & 0 deletions packages/tests/src/benchmark/Benchmark.res
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,104 @@ S.setGlobalConfig({
disableNanNumberCheck: true,
})

// Reported in https://gist.github.com/cknitt/4ac6813a3f3bc907187105e01a4324ca
module CrazyUnion = {
type rec test =
| A(array<test>)
| B
| C
| D
| E
| F
| G
| H
| I
| J
| K
| L
| M
| N
| O
| P
| Q
| R
| S
| T
| U
| V
| W
| X
| Y
| Z(array<test>)

let schema = S.recursive(schema =>
S.union([
S.object(s => {
s.tag("type", "A")
A(s.field("nested", S.array(schema)))
}),
S.literal(B),
S.literal(C),
S.literal(D),
S.literal(E),
S.literal(F),
S.literal(G),
S.literal(H),
S.literal(I),
S.literal(J),
S.literal(K),
S.literal(L),
S.literal(M),
S.literal(N),
S.literal(O),
S.literal(P),
S.literal(Q),
S.literal(R),
S.literal(S),
S.literal(T),
S.literal(U),
S.literal(V),
S.literal(W),
S.literal(X),
S.literal(Y),
S.object(s => {
s.tag("type", "Z")
Z(s.field("nested", S.array(schema)))
}),
])
)

let testData1 = Z(Array.make(~length=2, Z(Array.make(~length=2, Z(Array.make(~length=2, Y))))))

let _testData2 = A(Array.make(~length=2, A(Array.make(~length=2, A(Array.make(~length=2, B))))))

let test = () => {
Console.time("testData1 serialize")
let json = S.serializeOrRaiseWith(testData1, schema)
Console.timeEnd("testData1 serialize")

Console.time("testData1 parse")
let _ = S.parseOrRaiseWith(json, schema)
Console.timeEnd("testData1 parse")

// Console.time("testData2 serialize")
// let json = S.serializeOrRaiseWith(testData2, schema)
// Console.timeEnd("testData2 serialize")

// Console.time("testData2 parse")
// let _ = S.parseOrRaiseWith(json, schema)
// Console.timeEnd("testData2 parse")

Js.log((schema->Obj.magic)["parseOrThrow"]["toString"]())
}
}

// testData1 serialize: 5.414s
// testData1 parse: 5.519s
// testData2 serialize: 70.864ms
// testData2 parse: 70.967ms
CrazyUnion.test()

let data = makeTestObject()
Console.time("makeAdvancedObjectSchema")
let schema = makeAdvancedObjectSchema()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Generated by ReScript, PLEASE EDIT WITH CARE
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
83 changes: 83 additions & 0 deletions packages/tests/src/core/S_union_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,86 @@ module CknittelBugReport = {
)
})
}

// Reported in https://gist.github.com/cknitt/4ac6813a3f3bc907187105e01a4324ca
module CrazyUnion = {
type rec test =
| A(array<test>)
| B
| C
| D
| E
| F
| G
| H
| I
| J
| K
| L
| M
| N
| O
| P
| Q
| R
| S
| T
| U
| V
| W
| X
| Y
| Z(array<test>)

let schema = S.recursive(schema =>
S.union([
S.object(s => {
s.tag("type", "A")
A(s.field("nested", S.array(schema)))
}),
S.literal(B),
S.literal(C),
S.literal(D),
S.literal(E),
S.literal(F),
S.literal(G),
S.literal(H),
S.literal(I),
S.literal(J),
S.literal(K),
S.literal(L),
S.literal(M),
S.literal(N),
S.literal(O),
S.literal(P),
S.literal(Q),
S.literal(R),
S.literal(S),
S.literal(T),
S.literal(U),
S.literal(V),
S.literal(W),
S.literal(X),
S.literal(Y),
S.object(s => {
s.tag("type", "Z")
Z(s.field("nested", S.array(schema)))
}),
])
)

test("Compiled code snapshot of crazy union", t => {
S.setGlobalConfig({})
t->U.assertCompiledCode(
~schema,
~op=#Parse,
`i=>{let r0=i=>{let v6;try{if(!i||i.constructor!==Object){e[0](i)}let v0=i["type"],v1=i["nested"],v5=[];v0==="A"||e[1](v0);if(!Array.isArray(v1)){e[2](v1)}for(let v2=0;v2<v1.length;++v2){let v4;try{v4=r0(v1[v2])}catch(v3){if(v3&&v3.s===s){v3.path="[\\"nested\\"]"+\'["\'+v2+\'"]\'+v3.path}throw v3}v5.push(v4)}v6={"TAG":e[3],"_0":v5,}}catch(e0){try{i==="B"||e[4](i);v6=i}catch(e1){try{i==="C"||e[5](i);v6=i}catch(e2){try{i==="D"||e[6](i);v6=i}catch(e3){try{i==="E"||e[7](i);v6=i}catch(e4){try{i==="F"||e[8](i);v6=i}catch(e5){try{i==="G"||e[9](i);v6=i}catch(e6){try{i==="H"||e[10](i);v6=i}catch(e7){try{i==="I"||e[11](i);v6=i}catch(e8){try{i==="J"||e[12](i);v6=i}catch(e9){try{i==="K"||e[13](i);v6=i}catch(e10){try{i==="L"||e[14](i);v6=i}catch(e11){try{i==="M"||e[15](i);v6=i}catch(e12){try{i==="N"||e[16](i);v6=i}catch(e13){try{i==="O"||e[17](i);v6=i}catch(e14){try{i==="P"||e[18](i);v6=i}catch(e15){try{i==="Q"||e[19](i);v6=i}catch(e16){try{i==="R"||e[20](i);v6=i}catch(e17){try{i==="S"||e[21](i);v6=i}catch(e18){try{i==="T"||e[22](i);v6=i}catch(e19){try{i==="U"||e[23](i);v6=i}catch(e20){try{i==="V"||e[24](i);v6=i}catch(e21){try{i==="W"||e[25](i);v6=i}catch(e22){try{i==="X"||e[26](i);v6=i}catch(e23){try{i==="Y"||e[27](i);v6=i}catch(e24){try{if(!i||i.constructor!==Object){e[28](i)}let v7=i["type"],v8=i["nested"],v12=[];v7==="Z"||e[29](v7);if(!Array.isArray(v8)){e[30](v8)}for(let v9=0;v9<v8.length;++v9){let v11;try{v11=r0(v8[v9])}catch(v10){if(v10&&v10.s===s){v10.path="[\\"nested\\"]"+\'["\'+v9+\'"]\'+v10.path}throw v10}v12.push(v11)}v6={"TAG":e[31],"_0":v12,}}catch(e25){e[32]([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)}`,
)
S.setGlobalConfig({})
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{i==="B"||e[4](i);v6=i}catch(e1){try{i==="C"||e[5](i);v6=i}catch(e2){try{i==="D"||e[6](i);v6=i}catch(e3){try{i==="E"||e[7](i);v6=i}catch(e4){try{i==="F"||e[8](i);v6=i}catch(e5){try{i==="G"||e[9](i);v6=i}catch(e6){try{i==="H"||e[10](i);v6=i}catch(e7){try{i==="I"||e[11](i);v6=i}catch(e8){try{i==="J"||e[12](i);v6=i}catch(e9){try{i==="K"||e[13](i);v6=i}catch(e10){try{i==="L"||e[14](i);v6=i}catch(e11){try{i==="M"||e[15](i);v6=i}catch(e12){try{i==="N"||e[16](i);v6=i}catch(e13){try{i==="O"||e[17](i);v6=i}catch(e14){try{i==="P"||e[18](i);v6=i}catch(e15){try{i==="Q"||e[19](i);v6=i}catch(e16){try{i==="R"||e[20](i);v6=i}catch(e17){try{i==="S"||e[21](i);v6=i}catch(e18){try{i==="T"||e[22](i);v6=i}catch(e19){try{i==="U"||e[23](i);v6=i}catch(e20){try{i==="V"||e[24](i);v6=i}catch(e21){try{i==="W"||e[25](i);v6=i}catch(e22){try{i==="X"||e[26](i);v6=i}catch(e23){try{i==="Y"||e[27](i);v6=i}catch(e24){try{let v7=i["_0"],v11=[];if(i["TAG"]!==e[28]){e[29](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[30],"nested":v11,};if(!v12||v12.constructor!==Object){e[31](v12)}v6=v12}catch(e25){e[32]([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)}`,
)
})
}
5 changes: 4 additions & 1 deletion src/S_Core.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ function toJsResult(result) {
}
}

class RescriptSchemaError extends Error {
// let index = 0;
class RescriptSchemaError extends Error {
constructor(code, operation, path) {
// console.log(index)
// index = index + 1;
super();
this.operation = operation;
this.code = code;
Expand Down
3 changes: 3 additions & 0 deletions src/S_Core.res
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,11 @@ let toJsResult = (result: result<'value, error>): jsResult<'value> => {

module InternalError = {
%%raw(`
// let index = 0;
class RescriptSchemaError extends Error {
constructor(code, operation, path) {
// console.log(index)
// index = index + 1;
super();
this.operation = operation;
this.code = code;
Expand Down
Loading

0 comments on commit e440b08

Please sign in to comment.