aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/wallet/emscriptif-test.ts10
-rw-r--r--lib/wallet/emscriptif.ts112
-rw-r--r--testlib/selenium/testhost.html27
3 files changed, 69 insertions, 80 deletions
diff --git a/lib/wallet/emscriptif-test.ts b/lib/wallet/emscriptif-test.ts
index a3a9229bb..ddafa32bc 100644
--- a/lib/wallet/emscriptif-test.ts
+++ b/lib/wallet/emscriptif-test.ts
@@ -9,3 +9,13 @@ test("string hashing", (t: TestLib) => {
t.assert(h === hc, "must equal");
t.pass();
});
+
+test("signing", (t: TestLib) => {
+ let x = native.ByteArray.fromStringWithNull("hello taler");
+ let priv = native.EddsaPrivateKey.create();
+ let pub = priv.getPublicKey();
+ let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x);
+ let sig = native.eddsaSign(purpose, priv);
+ t.assert(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
+ t.pass();
+});
diff --git a/lib/wallet/emscriptif.ts b/lib/wallet/emscriptif.ts
index 4757fd8f4..b26f35ebd 100644
--- a/lib/wallet/emscriptif.ts
+++ b/lib/wallet/emscriptif.ts
@@ -193,6 +193,7 @@ export enum SignaturePurpose {
WALLET_COIN_DEPOSIT = 1201,
MASTER_DENOMINATION_KEY_VALIDITY = 1025,
WALLET_COIN_MELT = 1202,
+ TEST = 4242,
}
export enum RandomQuality {
@@ -217,7 +218,7 @@ export class HashContext implements ArenaObject {
if (!this.hashContextPtr) {
throw Error("assertion failed");
}
- emsc.hash_context_read(this.hashContextPtr, obj.getNative(), obj.size());
+ emsc.hash_context_read(this.hashContextPtr, obj.nativePtr, obj.size());
}
finish(h: HashCode) {
@@ -225,7 +226,7 @@ export class HashContext implements ArenaObject {
throw Error("assertion failed");
}
h.alloc();
- emsc.hash_context_finish(this.hashContextPtr, h.getNative());
+ emsc.hash_context_finish(this.hashContextPtr, h.nativePtr);
}
destroy(): void {
@@ -246,7 +247,12 @@ abstract class MallocArenaObject implements ArenaObject {
isWeak = false;
arena: Arena;
- abstract destroy(): void;
+ destroy(): void {
+ if (this._nativePtr && !this.isWeak) {
+ emsc.free(this.nativePtr);
+ this._nativePtr = undefined;
+ }
+ }
constructor(arena?: Arena) {
if (!arena) {
@@ -259,23 +265,6 @@ abstract class MallocArenaObject implements ArenaObject {
this.arena = arena;
}
- getNative(): number {
- // We want to allow latent allocation
- // of native wrappers, but we never want to
- // pass 'undefined' to emscripten.
- if (this._nativePtr === undefined) {
- throw Error("Native pointer not initialized");
- }
- return this._nativePtr;
- }
-
- free() {
- if (this.nativePtr && !this.isWeak) {
- emsc.free(this.nativePtr);
- this._nativePtr = undefined;
- }
- }
-
alloc(size: number) {
if (this._nativePtr !== undefined) {
throw Error("Double allocation");
@@ -283,19 +272,21 @@ abstract class MallocArenaObject implements ArenaObject {
this.nativePtr = emscAlloc.malloc(size);
}
- setNative(n: number) {
- if (n === undefined) {
+ set nativePtr(v: number) {
+ if (v === undefined) {
throw Error("Native pointer must be a number or null");
}
- this._nativePtr = n;
- }
-
- set nativePtr(v: number) {
- this.setNative(v);
+ this._nativePtr = v;
}
get nativePtr() {
- return this.getNative();
+ // We want to allow latent allocation
+ // of native wrappers, but we never want to
+ // pass 'undefined' to emscripten.
+ if (this._nativePtr === undefined) {
+ throw Error("Native pointer not initialized");
+ }
+ return this._nativePtr;
}
}
@@ -306,7 +297,10 @@ interface Arena {
}
-class DefaultArena implements Arena {
+/**
+ * Arena that must be manually destroyed.
+ */
+class SimpleArena implements Arena {
heap: Array<ArenaObject>;
constructor() {
@@ -326,22 +320,11 @@ class DefaultArena implements Arena {
}
-function mySetTimeout(ms: number, fn: () => void) {
- // We need to use different timeouts, depending on whether
- // we run in node or a web extension
- if ("function" === typeof setTimeout) {
- setTimeout(fn, ms);
- } else {
- chrome.extension.getBackgroundPage().setTimeout(fn, ms);
- }
-}
-
-
/**
* Arena that destroys all its objects once control has returned to the message
- * loop and a small interval has passed.
+ * loop.
*/
-class SyncArena extends DefaultArena {
+class SyncArena extends SimpleArena {
private isScheduled: boolean;
constructor() {
@@ -356,13 +339,9 @@ class SyncArena extends DefaultArena {
this.heap.push(obj);
}
- destroy() {
- super.destroy();
- }
-
private schedule() {
this.isScheduled = true;
- mySetTimeout(50, () => {
+ Promise.resolve().then(() => {
this.isScheduled = false;
this.destroy();
});
@@ -386,14 +365,9 @@ export class Amount extends MallocArenaObject {
}
}
- destroy() {
- super.free();
- }
-
-
static getZero(currency: string, a?: Arena): Amount {
let am = new Amount(undefined, a);
- let r = emsc.amount_get_zero(currency, am.getNative());
+ let r = emsc.amount_get_zero(currency, am.nativePtr);
if (r != GNUNET_OK) {
throw Error("invalid currency");
}
@@ -500,6 +474,7 @@ function countUtf8Bytes(str: string): number {
/**
* Managed reference to a contiguous block of memory in the Emscripten heap.
+ * Can be converted from / to a serialized representation.
* Should contain only data, not pointers.
*/
abstract class PackedArenaObject extends MallocArenaObject {
@@ -549,11 +524,6 @@ abstract class PackedArenaObject extends MallocArenaObject {
}
}
- destroy() {
- emsc.free(this.nativePtr);
- this.nativePtr = 0;
- }
-
hash(): HashCode {
var x = new HashCode();
x.alloc();
@@ -564,7 +534,7 @@ abstract class PackedArenaObject extends MallocArenaObject {
hexdump() {
let bytes: string[] = [];
for (let i = 0; i < this.size(); i++) {
- let b = Module.getValue(this.getNative() + i, "i8");
+ let b = Module.getValue(this.nativePtr + i, "i8");
b = (b + 256) % 256;
bytes.push("0".concat(b.toString(16)).slice(-2));
}
@@ -583,7 +553,7 @@ export class AmountNbo extends PackedArenaObject {
}
toJson(): any {
- let a = new DefaultArena();
+ let a = new SimpleArena();
let am = new Amount(undefined, a);
am.fromNbo(this);
let json = am.toJson();
@@ -722,7 +692,7 @@ function makeFromCrock(decodeFn: (p: number, s: number) => number) {
function fromCrock(s: string, a?: Arena) {
let obj = new this(a);
let buf = ByteArray.fromCrock(s);
- obj.setNative(decodeFn(buf.getNative(),
+ obj.setNative(decodeFn(buf.nativePtr,
buf.size()));
buf.destroy();
return obj;
@@ -987,7 +957,7 @@ export class AbsoluteTimeNbo extends PackedArenaObject {
}
let n = parseInt(m[1]) * 1000000;
// XXX: This only works up to 54 bit numbers.
- set64(x.getNative(), n);
+ set64(x.nativePtr, n);
return x;
}
@@ -1018,7 +988,7 @@ export class UInt64 extends PackedArenaObject {
static fromNumber(n: number): UInt64 {
let x = new UInt64();
x.alloc();
- set64(x.getNative(), n);
+ set64(x.nativePtr, n);
return x;
}
@@ -1032,7 +1002,7 @@ export class UInt32 extends PackedArenaObject {
static fromNumber(n: number): UInt64 {
let x = new UInt32();
x.alloc();
- set32(x.getNative(), n);
+ set32(x.nativePtr, n);
return x;
}
@@ -1128,9 +1098,9 @@ interface Encodeable {
function makeEncode(encodeFn: any) {
function encode(arena?: Arena) {
let ptr = emscAlloc.malloc(PTR_SIZE);
- let len = encodeFn(this.getNative(), ptr);
+ let len = encodeFn(this.nativePtr, ptr);
let res = new ByteArray(len, undefined, arena);
- res.setNative(Module.getValue(ptr, '*'));
+ res.nativePtr = Module.getValue(ptr, '*');
emsc.free(ptr);
return res;
}
@@ -1170,8 +1140,8 @@ export class RsaSignature extends MallocArenaObject implements Encodeable {
encode: (arena?: Arena) => ByteArray;
destroy() {
- emsc.rsa_signature_free(this.getNative());
- this.setNative(0);
+ emsc.rsa_signature_free(this.nativePtr);
+ this.nativePtr = 0;
}
}
mixinStatic(RsaSignature, makeFromCrock(emscAlloc.rsa_signature_decode));
@@ -1223,10 +1193,7 @@ export function eddsaVerify(purposeNum: number,
verify.nativePtr,
sig.nativePtr,
pub.nativePtr);
- if (r === GNUNET_OK) {
- return true;
- }
- return false;
+ return r === GNUNET_OK;
}
@@ -1275,5 +1242,4 @@ export function setupFreshCoin(secretSeed: TransferSecretP,
blindingKey.nativePtr = buf.nativePtr + priv.size();
return {priv, blindingKey};
-
}
diff --git a/testlib/selenium/testhost.html b/testlib/selenium/testhost.html
index b75c99e7e..5733ad945 100644
--- a/testlib/selenium/testhost.html
+++ b/testlib/selenium/testhost.html
@@ -10,7 +10,11 @@
<!-- for instrumentation to work, we have to use the non-csp version -->
<script src="/testlib/selenium/system.js"></script>
+ </head>
+ <body>
<script>
+ document.body.appendChild(document.createTextNode(`starting test`));
+ document.body.appendChild(document.createElement("br"));
var requestCoverage = false;
@@ -18,17 +22,26 @@
let oldTranslate = System.translate.bind(System);
System.translate = (load) => {
+ let srcP = oldTranslate(load);
if (!requestCoverage) {
- return oldTranslate(load);
+ return srcP;
}
- let inst = new Instrumenter();
- let srcP = oldTranslate(load);
- console.dir(load);
+ parser.href = load.name;
+ let modName = parser.pathname.substring(1);
+
+ if (/.*\/?taler-emscripten-lib.js/.test(load.name)) {
+ // don't instrument emscripten
+ document.body.appendChild(document.createTextNode(`not instrumenting ${modName}`));
+ document.body.appendChild(document.createElement("br"));
+ return srcP;
+ }
+
+ let inst = new Instrumenter();
+ document.body.appendChild(document.createTextNode(`instrumenting ${modName}`));
+ document.body.appendChild(document.createElement("br"));
return Promise.resolve(srcP).then((src) => {
- parser.href = load.name;
- let modName = parser.pathname.substring(1);
return inst.instrumentSync(src, modName);
});
}
@@ -44,5 +57,5 @@
},
});
</script>
- </head>
+ </body>
</html>