Skip to content

Commit

Permalink
Merge pull request #45 from unyt-org/fix-bigint-overflow
Browse files Browse the repository at this point in the history
Fix bigint overflow
  • Loading branch information
benStre authored Jan 21, 2024
2 parents 81c8c24 + be20156 commit 0326640
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
24 changes: 14 additions & 10 deletions compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -1482,7 +1483,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, <string>v_name, ACTION_TYPE.GET); // sync
if (base_type == BinaryCode.POINTER) Compiler.builder.addPointerByID(SCOPE.extract_var_scope, <string>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)
}
Expand Down Expand Up @@ -1681,11 +1682,14 @@ 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_32) 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;
SCOPE.data_view.setUint32(SCOPE.b_index, bigint_buffer.byteLength, true)
SCOPE.b_index+=Uint32Array.BYTES_PER_ELEMENT;

// bigint
SCOPE.uint8.set(bigint_buffer, SCOPE.b_index);
Expand Down Expand Up @@ -2175,7 +2179,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>|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>|void => {

// insert preemptive pointer
const id_buffer = typeof id == "string" ? hex2buffer(id, Pointer.MAX_POINTER_ID_SIZE, true) : id;
Expand Down Expand Up @@ -2205,7 +2209,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<any>):Promise<void>|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<any>):Promise<void>|void => {

Compiler.builder.handleRequiredBufferSize(SCOPE.b_index+1, SCOPE);
Compiler.builder.valueIndex(SCOPE);
Expand Down Expand Up @@ -2259,7 +2263,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;

Expand Down Expand Up @@ -2289,7 +2293,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);
}
},
Expand All @@ -2315,7 +2319,7 @@ export class Compiler {
Compiler.builder.insertExtractedVariable(<compiler_scope>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 <Array>
Expand Down Expand Up @@ -4592,7 +4596,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;
}

Expand Down
29 changes: 28 additions & 1 deletion runtime/pointers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<K=any, V extends RefLike = any> = (value:V extends RefLike<infer T> ? 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}
Expand Down Expand Up @@ -1998,6 +1999,20 @@ export class Pointer<T = any> extends Ref<T> {
else return val[propName]
}

#typeAssertions?: Conjunction<Assertion>

/**
* 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
Expand Down Expand Up @@ -2504,7 +2519,19 @@ export class Pointer<T = any> extends Ref<T> {
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<any>|void;

Expand Down
8 changes: 6 additions & 2 deletions runtime/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6694,9 +6694,13 @@ 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;

/** 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;
Expand Down
Binary file modified wasm/adapter/pkg/datex_wasm_bg.wasm
Binary file not shown.

0 comments on commit 0326640

Please sign in to comment.