diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 743bf9e232..29199aa415 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -616,7 +616,7 @@ proc pVarScoped(v: PNode; c: var Con; ri, res: PNode) = # unpacked tuple needs reset at every loop iteration res.add newTree(nkFastAsgn, v, genDefaultCall(v.typ, c, v.info)) elif {sfGlobal, sfThread} * v.sym.flags == {sfGlobal}: - c.graph.globalDestructors.add genDestroy(c, v) + c.graph.globalDestructors.add genDestroy(c, v) else: # We always translate 'var v = f()' into bitcopies. If 'v' is in a loop, # the destruction at the loop end will free the resources. Other assignments diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index aaad26f96e..b715e749ef 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -72,13 +72,17 @@ let cb64 = cbBase('+', '/') cb64safe = cbBase('-', '_') +const + cb64VM = cbBase('+', '/') + cb64safeVM = cbBase('-', '_') + const invalidChar = 255 -template encodeInternal(s: typed, alphabet: ptr array[64, char]): untyped = +template encodeSize(size: int): int = (size * 4 div 3) + 6 + +template encodeInternal(s, alphabet: typed): untyped = ## encodes `s` into base64 representation. - proc encodeSize(size: int): int = - return (size * 4 div 3) + 6 result.setLen(encodeSize(s.len)) @@ -94,7 +98,7 @@ template encodeInternal(s: typed, alphabet: ptr array[64, char]): untyped = n = exp inc inputIndex - template outputChar(x: untyped) = + template outputChar(x: typed) = result[outputIndex] = alphabet[x and 63] inc outputIndex @@ -129,6 +133,16 @@ template encodeInternal(s: typed, alphabet: ptr array[64, char]): untyped = result.setLen(outputIndex) +template encodeImpl() {.dirty.} = + when nimVM: + block: + let lookupTableVM = if safe: cb64safeVM else: cb64VM + encodeInternal(s, lookupTableVM) + else: + block: + let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64) + encodeInternal(s, lookupTable) + proc encode*[T: SomeInteger|char](s: openArray[T], safe = false): string = ## Encodes `s` into base64 representation. ## @@ -148,8 +162,7 @@ proc encode*[T: SomeInteger|char](s: openArray[T], safe = false): string = assert encode(['n', 'i', 'm']) == "bmlt" assert encode(@['n', 'i', 'm']) == "bmlt" assert encode([1, 2, 3, 4, 5]) == "AQIDBAU=" - let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64) - encodeInternal(s, lookupTable) + encodeImpl() proc encode*(s: string, safe = false): string = ## Encodes ``s`` into base64 representation. @@ -167,8 +180,7 @@ proc encode*(s: string, safe = false): string = ## * `decode proc<#decode,string>`_ for decoding a string runnableExamples: assert encode("Hello World") == "SGVsbG8gV29ybGQ=" - let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64) - encodeInternal(s, lookupTable) + encodeImpl() proc encodeMIME*(s: string, lineLen = 75, newLine = "\r\n"): string = ## Encodes ``s`` into base64 representation as lines. diff --git a/tests/stdlib/tbase64.nim b/tests/stdlib/tbase64.nim index e5b13642ce..19b1264373 100644 --- a/tests/stdlib/tbase64.nim +++ b/tests/stdlib/tbase64.nim @@ -1,8 +1,13 @@ discard """ - output: "OK" + output: '''YQ==''' + nimout: '''YQ==''' """ import base64 +import base64 +static: echo encode("a") +echo encode("a") + proc main() = doAssert encode("Hello World") == "SGVsbG8gV29ybGQ=" doAssert encode("leasure.") == "bGVhc3VyZS4=" @@ -54,6 +59,4 @@ proc main() = doAssert encode("", safe = true) == "" doAssert encode("the quick brown dog jumps over the lazy fox", safe = true) == "dGhlIHF1aWNrIGJyb3duIGRvZyBqdW1wcyBvdmVyIHRoZSBsYXp5IGZveA==" - echo "OK" - main()