JS codegen enhancements; still unusable

This commit is contained in:
Araq
2012-07-01 19:35:19 +02:00
parent ee1bcb6414
commit fe285b354d
9 changed files with 223 additions and 59 deletions

View File

@@ -35,7 +35,11 @@ proc `!$`*(h: THash): THash {.inline.} =
proc hashData*(Data: Pointer, Size: int): THash =
## hashes an array of bytes of size `size`
var h: THash = 0
var p = cast[cstring](Data)
when defined(ecmascript):
var p: cstring
asm """`p` = `Data`;"""
else:
var p = cast[cstring](Data)
var i = 0
var s = size
while s > 0:
@@ -44,9 +48,24 @@ proc hashData*(Data: Pointer, Size: int): THash =
Dec(s)
result = !$h
when defined(ecmascript):
var objectID = 0
proc hash*(x: Pointer): THash {.inline.} =
## efficient hashing of pointers
result = (cast[THash](x)) shr 3 # skip the alignment
when defined(ecmascript):
asm """
if (typeof `x` == "object") {
if ("_NimID" in `x`)
`result` = `x`["_NimID"];
else {
`result` = ++`objectID`;
`x`["_NimID"] = `result`;
}
}
"""
else:
result = (cast[THash](x)) shr 3 # skip the alignment
proc hash*(x: int): THash {.inline.} =
## efficient hashing of integers

View File

@@ -7,7 +7,11 @@
# distribution, for details about the copyright.
#
proc alert*(s: cstring) {.importc, nodecl.}
when defined(nodejs):
proc alert*(s: cstring) {.importc: "console.log", nodecl.}
else:
proc alert*(s: cstring) {.importc, nodecl.}
proc log*(s: cstring) {.importc: "console.log", nodecl.}
type
@@ -100,7 +104,7 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
alert(buf)
asm """throw `e`;"""
proc reraiseException() =
proc reraiseException() {.compilerproc, noStackFrame.} =
if excHandler == nil:
raise newException(ENoExceptionToReraise, "no exception to reraise")
else:
@@ -295,27 +299,40 @@ type
setAttribute*: proc (name, value: cstring)
setAttributeNode*: proc (attr: ref TNode)
var
document {.importc, nodecl.}: ref TDocument
when defined(nodejs):
proc ewriteln(x: cstring) = log(x)
proc rawEcho {.compilerproc, nostackframe.} =
asm """
var buf = "";
for (var i = 0; i < arguments.length; ++i) {
buf += `toEcmaStr`(arguments[i]);
}
console.log(buf);
"""
proc ewriteln(x: cstring) =
var node = document.getElementsByTagName("body")[0]
if node != nil:
node.appendChild(document.createTextNode(x))
else:
var
document {.importc, nodecl.}: ref TDocument
proc ewriteln(x: cstring) =
var node = document.getElementsByTagName("body")[0]
if node != nil:
node.appendChild(document.createTextNode(x))
node.appendChild(document.createElement("br"))
else:
raise newException(EInvalidValue, "<body> element does not exist yet!")
proc rawEcho {.compilerproc.} =
var node = document.getElementsByTagName("body")[0]
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
asm """
for (var i = 0; i < arguments.length; ++i) {
var x = `toEcmaStr`(arguments[i]);
`node`.appendChild(document.createTextNode(x))
}
"""
node.appendChild(document.createElement("br"))
else:
raise newException(EInvalidValue, "<body> element does not exist yet!")
proc rawEcho {.compilerproc.} =
var node = document.getElementsByTagName("body")[0]
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
asm """
for (var i = 0; i < arguments.length; ++i) {
var x = `toEcmaStr`(arguments[i]);
`node`.appendChild(document.createTextNode(x))
}
"""
node.appendChild(document.createElement("br"))
# Arithmetic:
proc addInt(a, b: int): int {.noStackFrame, compilerproc.} =
@@ -474,7 +491,7 @@ proc isFatPointer(ti: PNimType): bool =
proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.exportc.} =
proc NimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
case n.kind
of nkNone: sysAssert(false, "NimCopyAux")
of nkSlot:
@@ -525,6 +542,37 @@ proc NimCopy(x: pointer, ti: PNimType): pointer =
else:
result = x
proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} =
case ti.kind
of tyPtr, tyRef, tyVar, tyNil:
if not isFatPointer(ti):
result = nil
else:
asm """
`result` = [null, 0];
"""
of tySet:
asm """
`result` = {};
"""
of tyTuple, tyObject:
if ti.kind == tyObject:
asm "`result` = {m_type: `ti`};"
else:
asm "`result` = {};"
of tySequence, tyOpenArray:
asm """
`result` = [];
"""
of tyArrayConstr, tyArray:
asm """
`result` = new Array(`x`.length);
for (var i = 0; i < `x`.length; ++i) {
`result`[i] = genericReset(`x`[i], `ti`.base);
}
"""
else:
result = nil
proc ArrayConstr(len: int, value: pointer, typ: PNimType): pointer {.
noStackFrame, compilerproc.} =
@@ -552,4 +600,13 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
raise newException(EInvalidObjectConversion, "invalid object conversion")
x = x.base
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
# checks if obj is of type subclass:
var x = obj
if x == subclass: return true # optimized fast path
while x != subclass:
if x == nil: return false
x = x.base
return true
{.pop.}