Automatic deref for everything but pointers in asm/emit (#8891)

Fixes #7249
This commit is contained in:
LemonBoy 2018-09-07 01:54:59 +02:00 • committed by Andreas Rumpf
commit af1e84f54d
5 changed files with 42 additions and 10 deletions

View file

@ -764,11 +764,22 @@ proc genAsmOrEmitStmt(p: PProc, n: PNode) =
of nkSym: of nkSym:
let v = it.sym let v = it.sym
# for backwards compatibility we don't deref syms here :-( # for backwards compatibility we don't deref syms here :-(
if v.kind in {skVar, skLet, skTemp, skConst, skResult, skParam, skForVar}: if false:
p.body.add mangleName(p.module, v) discard
else: else:
var r: TCompRes var r: TCompRes
gen(p, it, r) gen(p, it, r)
if it.typ.kind == tyPointer:
# A fat pointer is disguised as an array
r.res = r.address
r.address = nil
elif r.typ == etyBaseIndex:
# Deference first
r.res = "$1[$2]" % [r.address, r.res]
r.address = nil
r.typ = etyNone
p.body.add(r.rdLoc) p.body.add(r.rdLoc)
else: else:
var r: TCompRes var r: TCompRes

View file

@ -2741,12 +2741,12 @@ type
when defined(JS): when defined(JS):
proc add*(x: var string, y: cstring) {.asmNoStackFrame.} = proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
asm """ asm """
var len = `x`[0].length-1; var len = `x`.length-1;
for (var i = 0; i < `y`.length; ++i) { for (var i = 0; i < `y`.length; ++i) {
`x`[0][len] = `y`.charCodeAt(i); `x`[len] = `y`.charCodeAt(i);
++len; ++len;
} }
`x`[0][len] = 0 `x`[len] = 0
""" """
proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".}

21
tests/js/t7249.nim Normal file
View file

@ -0,0 +1,21 @@
discard """
output: '''
a -> 2
a <- 2
'''
"""
import jsffi
var a = JsAssoc[cstring, int]{a: 2}
for z, b in a:
echo z, " -> ", b
proc f =
var a = JsAssoc[cstring, int]{a: 2}
for z, b in a:
echo z, " <- ", b
f()

View file

@ -27,10 +27,10 @@ block:
var global = T(a: 11, b: "foo") var global = T(a: 11, b: "foo")
proc test(): bool = proc test(): bool =
var obj = T(a: 11, b: "foo") var obj = T(a: 11, b: "foo")
{. emit: [result, " = (", obj.addr[], "[0].a == 11);"] .} {. emit: [result, " = (", obj.addr[], ".a == 11);"] .}
{. emit: [result, " = ", result, " && (", obj.addr[], "[0].b == \"foo\");"] .} {. emit: [result, " = ", result, " && (", obj.addr[], ".b == \"foo\");"] .}
{. emit: [result, " = ", result, " && (", global, "[0].a == 11);"] .} {. emit: [result, " = ", result, " && (", global, ".a == 11);"] .}
{. emit: [result, " = ", result, " && (", global, "[0].b == \"foo\");"] .} {. emit: [result, " = ", result, " && (", global, ".b == \"foo\");"] .}
echo test() echo test()
# Test addr of field: # Test addr of field:

View file

@ -45,7 +45,7 @@ block: # Test compile-time binary data generation, invalid unicode
block: # Test unicode strings block: # Test unicode strings
const constStr = "Привет!" const constStr = "Привет!"
var jsStr : cstring var jsStr : cstring
{.emit: """`jsStr`[0] = "Привет!";""".} {.emit: """`jsStr` = "Привет!";""".}
doAssert($jsStr == constStr) doAssert($jsStr == constStr)
var runtimeStr = "При" var runtimeStr = "При"