From c59e101a9e06f451fa1605d6e96f174807eeea19 Mon Sep 17 00:00:00 2001 From: benStre Date: Wed, 17 Jan 2024 01:33:13 +0100 Subject: [PATCH 1/5] add assert method for primitive pointers --- compiler/compiler.ts | 14 +++++++------- runtime/pointers.ts | 29 ++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/compiler/compiler.ts b/compiler/compiler.ts index c8b8d0d9..d3c6119f 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -1482,7 +1482,7 @@ export class Compiler { // insert at top of scope dxb if new if (insert_new) { // pointer - if (base_type == BinaryCode.POINTER) Compiler.builder.addPointerByID(SCOPE.extract_var_scope, v_name, ACTION_TYPE.GET); // sync + if (base_type == BinaryCode.POINTER) Compiler.builder.addPointerByID(SCOPE.extract_var_scope, v_name, ACTION_TYPE.GET, undefined, undefined, NOT_EXISTING); // sync // variable/label else Compiler.builder.insertVariable(SCOPE.extract_var_scope, v_name, ACTION_TYPE.GET, undefined, base_type) } @@ -2175,7 +2175,7 @@ export class Compiler { } }, - addPointerByID: (SCOPE:compiler_scope|extract_var_scope, id:string|Uint8Array, action_type:ACTION_TYPE = ACTION_TYPE.GET, action_specifier?:BinaryCode, init_brackets = false, value:any = NOT_EXISTING):Promise|void => { + addPointerByID: (SCOPE:compiler_scope|extract_var_scope, id:string|Uint8Array, action_type:ACTION_TYPE = ACTION_TYPE.GET, action_specifier?:BinaryCode, init_brackets = false, value?:any):Promise|void => { // insert preemptive pointer const id_buffer = typeof id == "string" ? hex2buffer(id, Pointer.MAX_POINTER_ID_SIZE, true) : id; @@ -2201,7 +2201,7 @@ export class Compiler { }, // just $aabbcc = - addPointerNormal: (SCOPE:compiler_scope|extract_var_scope, id:string|Uint8Array, action_type:ACTION_TYPE = ACTION_TYPE.GET, action_specifier?:BinaryCode, init_brackets = false, value:any = NOT_EXISTING, transform_scope?: Scope):Promise|void => { + addPointerNormal: (SCOPE:compiler_scope|extract_var_scope, id:string|Uint8Array, action_type:ACTION_TYPE = ACTION_TYPE.GET, action_specifier?:BinaryCode, init_brackets = false, value?:any, transform_scope?: Scope):Promise|void => { Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+1, SCOPE); Compiler.builder.valueIndex(SCOPE); @@ -2255,7 +2255,7 @@ export class Compiler { Compiler.builder.addPointerNormal(SCOPE, id, ACTION_TYPE.INIT, undefined, true, ptr.val, (ptr.force_local_transform && ptr.transform_scope) ? ptr.transform_scope : undefined); // sync Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+1, SCOPE); SCOPE.uint8[SCOPE.b_index++] = BinaryCode.CLOSE_AND_STORE; - Compiler.builder.addPointerNormal(SCOPE, id, ACTION_TYPE.GET); // sync + Compiler.builder.addPointerNormal(SCOPE, id, ACTION_TYPE.GET, undefined, undefined, ptr.val); // sync Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+1, SCOPE); SCOPE.uint8[SCOPE.b_index++] = BinaryCode.SUBSCOPE_END; @@ -2285,7 +2285,7 @@ export class Compiler { deferSizeIndex = SCOPE.b_index; SCOPE.b_index += Uint32Array.BYTES_PER_ELEMENT; } - Compiler.builder.addPointerNormal(SCOPE, id, ACTION_TYPE.GET); // sync + Compiler.builder.addPointerNormal(SCOPE, id, ACTION_TYPE.GET, undefined, undefined, NOT_EXISTING); // sync if (defer) SCOPE.data_view.setUint32(deferSizeIndex, SCOPE.b_index-deferSizeIndex-Uint32Array.BYTES_PER_ELEMENT, true); } }, @@ -2311,7 +2311,7 @@ export class Compiler { Compiler.builder.insertExtractedVariable(SCOPE, BinaryCode.POINTER, buffer2hex(p.id_buffer)); } // add normally - else return Compiler.builder.addPointerByID (SCOPE, p.id_buffer, action_type, action_specifier) + else return Compiler.builder.addPointerByID (SCOPE, p.id_buffer, action_type, action_specifier, undefined, NOT_EXISTING) }, // add @@ -4588,7 +4588,7 @@ export class Compiler { Compiler.builder.insertExtractedVariable(SCOPE, BinaryCode.POINTER, id) } // insert normally - else await Compiler.builder.addPointerByID(SCOPE, id, action_type, action_specifier, init_brackets) + else await Compiler.builder.addPointerByID(SCOPE, id, action_type, action_specifier, init_brackets, NOT_EXISTING) isEffectiveValue = true; } diff --git a/runtime/pointers.ts b/runtime/pointers.ts index 17d486bd..4412b773 100644 --- a/runtime/pointers.ts +++ b/runtime/pointers.ts @@ -28,6 +28,7 @@ import { IterableWeakSet } from "../utils/iterable-weak-set.ts"; import { IterableWeakMap } from "../utils/iterable-weak-map.ts"; import { LazyPointer } from "./lazy-pointer.ts"; import { ReactiveArrayMethods } from "../types/reactive-methods/array.ts"; +import { Assertion } from "../types/assertion.ts"; export type observe_handler = (value:V extends RefLike ? T : V, key?:K, type?:Ref.UPDATE_TYPE, transform?:boolean, is_child_update?:boolean, previous?: any, atomic_id?:symbol)=>void|boolean export type observe_options = {types?:Ref.UPDATE_TYPE[], ignore_transforms?:boolean, recursive?:boolean} @@ -1997,6 +1998,20 @@ export class Pointer extends Ref { else return val[propName] } + #typeAssertions?: Conjunction + + /** + * Add an assertion that is validated when the pointer value is changed + * Only works for primitive pointers + * @param assertion + */ + public assert(assertion:(val:any)=>boolean|string|undefined|null) { + if (!this.is_js_primitive) throw new PointerError("Assertions are not yet supported for non-primitive pointer") + if (!this.#typeAssertions) this.#typeAssertions = new Conjunction(); + this.#typeAssertions.add(Assertion.get(undefined, assertion, false)); + return this; + } + /** * Changes the id of the pointer to point to the new origin (and also changes the .origin) * @param new_owner @@ -2503,7 +2518,19 @@ export class Pointer extends Ref { throw new ValueError("Invalid value type for transform pointer "+this.idString()+": " + newType + (error ? " - " + error : "")); } } - else if ((v!==null&&v!==undefined) && !Type.matchesType(newType, this.type)) throw new ValueError("Invalid value type for pointer "+this.idString()+": " + newType + " - must be " + this.type); + else if ((v!==null&&v!==undefined)) { + if ( + // validate pointer type + !Type.matchesType(newType, this.type, val, true) || + // validate custom type assertions + ( + this.#typeAssertions && + !Type.matchesType(newType, this.#typeAssertions, val, true) + ) + ) { + throw new ValueError("Invalid value type for pointer "+this.idString()+": " + newType + " - must be " + this.type); + } + } let updatePromise: Promise|void; From 51c6455d2aad8d4570100db6eaf46431c71ff85d Mon Sep 17 00:00:00 2001 From: benStre Date: Wed, 17 Jan 2024 11:17:32 +0100 Subject: [PATCH 2/5] fix bigint overflow --- compiler/compiler.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/compiler.ts b/compiler/compiler.ts index d3c6119f..5fcf51ae 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -1683,6 +1683,9 @@ export class Compiler { const bigint_buffer = Quantity.bigIntToBuffer(BigInt(i < 0 ? -i : i)); Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+(Uint16Array.BYTES_PER_ELEMENT*2)+bigint_buffer.byteLength, SCOPE); + // invalid bigint size + if (bigint_buffer.byteLength > Compiler.MAX_UINT_16) throw new CompilerError("Integer too big"); + // buffer size SCOPE.data_view.setUint16(SCOPE.b_index, bigint_buffer.byteLength, true) SCOPE.b_index+=Uint16Array.BYTES_PER_ELEMENT; From cca4ee51f0a94bce634c7d210ebb72701e6ce8f8 Mon Sep 17 00:00:00 2001 From: benStre Date: Wed, 17 Jan 2024 11:19:50 +0100 Subject: [PATCH 3/5] increase bigint buffer size to uint32 --- compiler/compiler.ts | 7 ++++--- runtime/runtime.ts | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/compiler.ts b/compiler/compiler.ts index 5fcf51ae..9b148b51 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -310,6 +310,7 @@ export class Compiler { static MIN_INT_16 = -32_768; static MAX_UINT_16 = 65_535; + static MAX_UINT_32 = 4_294_967_295; static readonly signature_size = 96 // 256; @@ -1681,13 +1682,13 @@ export class Compiler { SCOPE.uint8[SCOPE.b_index++] = i < 0 ? 0 : 1; // 0 for negative, 1 for positive (and 0) const bigint_buffer = Quantity.bigIntToBuffer(BigInt(i < 0 ? -i : i)); - Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+(Uint16Array.BYTES_PER_ELEMENT*2)+bigint_buffer.byteLength, SCOPE); + Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+Uint32Array.BYTES_PER_ELEMENT+bigint_buffer.byteLength, SCOPE); // invalid bigint size - if (bigint_buffer.byteLength > Compiler.MAX_UINT_16) throw new CompilerError("Integer too big"); + if (bigint_buffer.byteLength > Compiler.MAX_UINT_32) throw new CompilerError("Integer too big"); // buffer size - SCOPE.data_view.setUint16(SCOPE.b_index, bigint_buffer.byteLength, true) + SCOPE.data_view.setUint32(SCOPE.b_index, bigint_buffer.byteLength, true) SCOPE.b_index+=Uint16Array.BYTES_PER_ELEMENT; // bigint diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 9fc00b39..451a1d5b 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -6690,8 +6690,8 @@ export class Runtime { const sign = SCOPE.buffer_views.uint8[SCOPE.current_index++] == 0 ? -1n : 1n; // 0 for negative, 1 for positive (and 0) // buffer size - const size = SCOPE.buffer_views.data_view.getUint16(SCOPE.current_index, true) - SCOPE.current_index+=Uint16Array.BYTES_PER_ELEMENT; + const size = SCOPE.buffer_views.data_view.getUint32(SCOPE.current_index, true) + SCOPE.current_index+=Uint32Array.BYTES_PER_ELEMENT; // bigint from buffer const bigint_buffer = SCOPE.buffer_views.uint8.subarray(SCOPE.current_index, SCOPE.current_index+=size); From 6180658cd8802a6b6bed9b443be2d9ef063b9c90 Mon Sep 17 00:00:00 2001 From: benStre Date: Wed, 17 Jan 2024 11:26:17 +0100 Subject: [PATCH 4/5] fix bigint uint32 size --- compiler/compiler.ts | 2 +- runtime/runtime.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/compiler.ts b/compiler/compiler.ts index 9b148b51..9aaeb8b4 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -1689,7 +1689,7 @@ export class Compiler { // buffer size SCOPE.data_view.setUint32(SCOPE.b_index, bigint_buffer.byteLength, true) - SCOPE.b_index+=Uint16Array.BYTES_PER_ELEMENT; + SCOPE.b_index+=Uint32Array.BYTES_PER_ELEMENT; // bigint SCOPE.uint8.set(bigint_buffer, SCOPE.b_index); diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 451a1d5b..8f2914cc 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -6693,6 +6693,10 @@ export class Runtime { const size = SCOPE.buffer_views.data_view.getUint32(SCOPE.current_index, true) SCOPE.current_index+=Uint32Array.BYTES_PER_ELEMENT; + /** wait for buffer */ + if (SCOPE.current_index+size > SCOPE.buffer_views.uint8.byteLength) return Runtime.runtime_actions.waitForBuffer(SCOPE); + /********************/ + // bigint from buffer const bigint_buffer = SCOPE.buffer_views.uint8.subarray(SCOPE.current_index, SCOPE.current_index+=size); const bigint = Quantity.bufferToBigInt(bigint_buffer) * sign; From f7e623c078d2973fe02d7ae1a17bc708e2a22b0e Mon Sep 17 00:00:00 2001 From: benStre Date: Wed, 17 Jan 2024 11:26:35 +0100 Subject: [PATCH 5/5] update datex decompiler --- wasm/adapter/pkg/datex_wasm_bg.wasm | Bin 806339 -> 806334 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/wasm/adapter/pkg/datex_wasm_bg.wasm b/wasm/adapter/pkg/datex_wasm_bg.wasm index b3e3b221c58e978e819e97df7ce887d4eb733628..1cb3ad2ad8719815c573f45f14af232d4baf91ed 100644 GIT binary patch delta 78 zcmX>++i>4(!wsxlj2kwyamDm8&f1(jqn(3s<>c23B%3)GwsS6I1Y#y2W(HywAZ7(( WHXvpPVh$kY1Y)l3oC~>ktpNanARG_? delta 83 zcmdlt+wkyg!wsxlj9WLeamDm8&flCoqn%^&y+x92td9TxGZ!|qENo|4$OyztK+Fup bEI`Z(#B4y!4#XTl%n8I?+gTQJ?^*)@Bu5?R