Skip to content

Instantly share code, notes, and snippets.

@death667b
Created February 27, 2017 02:22
Show Gist options
  • Save death667b/5e18f59cbfa97f82f844b54cdb28a932 to your computer and use it in GitHub Desktop.
Save death667b/5e18f59cbfa97f82f844b54cdb28a932 to your computer and use it in GitHub Desktop.
"use strict";
(function() {
Error.stackTraceLimit = Infinity;
var $global, $module;
if (typeof window !== "undefined") { /* web page */
$global = window;
} else if (typeof self !== "undefined") { /* web worker */
$global = self;
} else if (typeof global !== "undefined") { /* Node.js */
$global = global;
$global.require = require;
} else { /* others (e.g. Nashorn) */
$global = this;
}
if ($global === undefined || $global.Array === undefined) {
throw new Error("no global object found");
}
if (typeof module !== "undefined") {
$module = module;
}
var $packages = {}, $idCounter = 0;
var $keys = function(m) { return m ? Object.keys(m) : []; };
var $flushConsole = function() {};
var $throwRuntimeError; /* set by package "runtime" */
var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); };
var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); };
var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; };
var $unused = function(v) {};
var $mapArray = function(array, f) {
var newArray = new array.constructor(array.length);
for (var i = 0; i < array.length; i++) {
newArray[i] = f(array[i]);
}
return newArray;
};
var $methodVal = function(recv, name) {
var vals = recv.$methodVals || {};
recv.$methodVals = vals; /* noop for primitives */
var f = vals[name];
if (f !== undefined) {
return f;
}
var method = recv[name];
f = function() {
$stackDepthOffset--;
try {
return method.apply(recv, arguments);
} finally {
$stackDepthOffset++;
}
};
vals[name] = f;
return f;
};
var $methodExpr = function(typ, name) {
var method = typ.prototype[name];
if (method.$expr === undefined) {
method.$expr = function() {
$stackDepthOffset--;
try {
if (typ.wrapped) {
arguments[0] = new typ(arguments[0]);
}
return Function.call.apply(method, arguments);
} finally {
$stackDepthOffset++;
}
};
}
return method.$expr;
};
var $ifaceMethodExprs = {};
var $ifaceMethodExpr = function(name) {
var expr = $ifaceMethodExprs["$" + name];
if (expr === undefined) {
expr = $ifaceMethodExprs["$" + name] = function() {
$stackDepthOffset--;
try {
return Function.call.apply(arguments[0][name], arguments);
} finally {
$stackDepthOffset++;
}
};
}
return expr;
};
var $subslice = function(slice, low, high, max) {
if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) {
$throwRuntimeError("slice bounds out of range");
}
var s = new slice.constructor(slice.$array);
s.$offset = slice.$offset + low;
s.$length = slice.$length - low;
s.$capacity = slice.$capacity - low;
if (high !== undefined) {
s.$length = high - low;
}
if (max !== undefined) {
s.$capacity = max - low;
}
return s;
};
var $substring = function(str, low, high) {
if (low < 0 || high < low || high > str.length) {
$throwRuntimeError("slice bounds out of range");
}
return str.substring(low, high);
};
var $sliceToArray = function(slice) {
if (slice.$length === 0) {
return [];
}
if (slice.$array.constructor !== Array) {
return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length);
}
return slice.$array.slice(slice.$offset, slice.$offset + slice.$length);
};
var $decodeRune = function(str, pos) {
var c0 = str.charCodeAt(pos);
if (c0 < 0x80) {
return [c0, 1];
}
if (c0 !== c0 || c0 < 0xC0) {
return [0xFFFD, 1];
}
var c1 = str.charCodeAt(pos + 1);
if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) {
return [0xFFFD, 1];
}
if (c0 < 0xE0) {
var r = (c0 & 0x1F) << 6 | (c1 & 0x3F);
if (r <= 0x7F) {
return [0xFFFD, 1];
}
return [r, 2];
}
var c2 = str.charCodeAt(pos + 2);
if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) {
return [0xFFFD, 1];
}
if (c0 < 0xF0) {
var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F);
if (r <= 0x7FF) {
return [0xFFFD, 1];
}
if (0xD800 <= r && r <= 0xDFFF) {
return [0xFFFD, 1];
}
return [r, 3];
}
var c3 = str.charCodeAt(pos + 3);
if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) {
return [0xFFFD, 1];
}
if (c0 < 0xF8) {
var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F);
if (r <= 0xFFFF || 0x10FFFF < r) {
return [0xFFFD, 1];
}
return [r, 4];
}
return [0xFFFD, 1];
};
var $encodeRune = function(r) {
if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) {
r = 0xFFFD;
}
if (r <= 0x7F) {
return String.fromCharCode(r);
}
if (r <= 0x7FF) {
return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F));
}
if (r <= 0xFFFF) {
return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));
}
return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F));
};
var $stringToBytes = function(str) {
var array = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
array[i] = str.charCodeAt(i);
}
return array;
};
var $bytesToString = function(slice) {
if (slice.$length === 0) {
return "";
}
var str = "";
for (var i = 0; i < slice.$length; i += 10000) {
str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000)));
}
return str;
};
var $stringToRunes = function(str) {
var array = new Int32Array(str.length);
var rune, j = 0;
for (var i = 0; i < str.length; i += rune[1], j++) {
rune = $decodeRune(str, i);
array[j] = rune[0];
}
return array.subarray(0, j);
};
var $runesToString = function(slice) {
if (slice.$length === 0) {
return "";
}
var str = "";
for (var i = 0; i < slice.$length; i++) {
str += $encodeRune(slice.$array[slice.$offset + i]);
}
return str;
};
var $copyString = function(dst, src) {
var n = Math.min(src.length, dst.$length);
for (var i = 0; i < n; i++) {
dst.$array[dst.$offset + i] = src.charCodeAt(i);
}
return n;
};
var $copySlice = function(dst, src) {
var n = Math.min(src.$length, dst.$length);
$copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem);
return n;
};
var $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) {
if (n === 0 || (dst === src && dstOffset === srcOffset)) {
return;
}
if (src.subarray) {
dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset);
return;
}
switch (elem.kind) {
case $kindArray:
case $kindStruct:
if (dst === src && dstOffset > srcOffset) {
for (var i = n - 1; i >= 0; i--) {
elem.copy(dst[dstOffset + i], src[srcOffset + i]);
}
return;
}
for (var i = 0; i < n; i++) {
elem.copy(dst[dstOffset + i], src[srcOffset + i]);
}
return;
}
if (dst === src && dstOffset > srcOffset) {
for (var i = n - 1; i >= 0; i--) {
dst[dstOffset + i] = src[srcOffset + i];
}
return;
}
for (var i = 0; i < n; i++) {
dst[dstOffset + i] = src[srcOffset + i];
}
};
var $clone = function(src, type) {
var clone = type.zero();
type.copy(clone, src);
return clone;
};
var $pointerOfStructConversion = function(obj, type) {
if(obj.$proxies === undefined) {
obj.$proxies = {};
obj.$proxies[obj.constructor.string] = obj;
}
var proxy = obj.$proxies[type.string];
if (proxy === undefined) {
var properties = {};
for (var i = 0; i < type.elem.fields.length; i++) {
(function(fieldProp) {
properties[fieldProp] = {
get: function() { return obj[fieldProp]; },
set: function(value) { obj[fieldProp] = value; }
};
})(type.elem.fields[i].prop);
}
proxy = Object.create(type.prototype, properties);
proxy.$val = proxy;
obj.$proxies[type.string] = proxy;
proxy.$proxies = obj.$proxies;
}
return proxy;
};
var $append = function(slice) {
return $internalAppend(slice, arguments, 1, arguments.length - 1);
};
var $appendSlice = function(slice, toAppend) {
if (toAppend.constructor === String) {
var bytes = $stringToBytes(toAppend);
return $internalAppend(slice, bytes, 0, bytes.length);
}
return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);
};
var $internalAppend = function(slice, array, offset, length) {
if (length === 0) {
return slice;
}
var newArray = slice.$array;
var newOffset = slice.$offset;
var newLength = slice.$length + length;
var newCapacity = slice.$capacity;
if (newLength > newCapacity) {
newOffset = 0;
newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4));
if (slice.$array.constructor === Array) {
newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length);
newArray.length = newCapacity;
var zero = slice.constructor.elem.zero;
for (var i = slice.$length; i < newCapacity; i++) {
newArray[i] = zero();
}
} else {
newArray = new slice.$array.constructor(newCapacity);
newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length));
}
}
$copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem);
var newSlice = new slice.constructor(newArray);
newSlice.$offset = newOffset;
newSlice.$length = newLength;
newSlice.$capacity = newCapacity;
return newSlice;
};
var $equal = function(a, b, type) {
if (type === $jsObjectPtr) {
return a === b;
}
switch (type.kind) {
case $kindComplex64:
case $kindComplex128:
return a.$real === b.$real && a.$imag === b.$imag;
case $kindInt64:
case $kindUint64:
return a.$high === b.$high && a.$low === b.$low;
case $kindArray:
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (!$equal(a[i], b[i], type.elem)) {
return false;
}
}
return true;
case $kindStruct:
for (var i = 0; i < type.fields.length; i++) {
var f = type.fields[i];
if (!$equal(a[f.prop], b[f.prop], f.typ)) {
return false;
}
}
return true;
case $kindInterface:
return $interfaceIsEqual(a, b);
default:
return a === b;
}
};
var $interfaceIsEqual = function(a, b) {
if (a === $ifaceNil || b === $ifaceNil) {
return a === b;
}
if (a.constructor !== b.constructor) {
return false;
}
if (a.constructor === $jsObjectPtr) {
return a.object === b.object;
}
if (!a.constructor.comparable) {
$throwRuntimeError("comparing uncomparable type " + a.constructor.string);
}
return $equal(a.$val, b.$val, a.constructor);
};
var $min = Math.min;
var $mod = function(x, y) { return x % y; };
var $parseInt = parseInt;
var $parseFloat = function(f) {
if (f !== undefined && f !== null && f.constructor === Number) {
return f;
}
return parseFloat(f);
};
var $froundBuf = new Float32Array(1);
var $fround = Math.fround || function(f) {
$froundBuf[0] = f;
return $froundBuf[0];
};
var $imul = Math.imul || function(a, b) {
var ah = (a >>> 16) & 0xffff;
var al = a & 0xffff;
var bh = (b >>> 16) & 0xffff;
var bl = b & 0xffff;
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) >> 0);
};
var $floatKey = function(f) {
if (f !== f) {
$idCounter++;
return "NaN$" + $idCounter;
}
return String(f);
};
var $flatten64 = function(x) {
return x.$high * 4294967296 + x.$low;
};
var $shiftLeft64 = function(x, y) {
if (y === 0) {
return x;
}
if (y < 32) {
return new x.constructor(x.$high << y | x.$low >>> (32 - y), (x.$low << y) >>> 0);
}
if (y < 64) {
return new x.constructor(x.$low << (y - 32), 0);
}
return new x.constructor(0, 0);
};
var $shiftRightInt64 = function(x, y) {
if (y === 0) {
return x;
}
if (y < 32) {
return new x.constructor(x.$high >> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);
}
if (y < 64) {
return new x.constructor(x.$high >> 31, (x.$high >> (y - 32)) >>> 0);
}
if (x.$high < 0) {
return new x.constructor(-1, 4294967295);
}
return new x.constructor(0, 0);
};
var $shiftRightUint64 = function(x, y) {
if (y === 0) {
return x;
}
if (y < 32) {
return new x.constructor(x.$high >>> y, (x.$low >>> y | x.$high << (32 - y)) >>> 0);
}
if (y < 64) {
return new x.constructor(0, x.$high >>> (y - 32));
}
return new x.constructor(0, 0);
};
var $mul64 = function(x, y) {
var high = 0, low = 0;
if ((y.$low & 1) !== 0) {
high = x.$high;
low = x.$low;
}
for (var i = 1; i < 32; i++) {
if ((y.$low & 1<<i) !== 0) {
high += x.$high << i | x.$low >>> (32 - i);
low += (x.$low << i) >>> 0;
}
}
for (var i = 0; i < 32; i++) {
if ((y.$high & 1<<i) !== 0) {
high += x.$low << i;
}
}
return new x.constructor(high, low);
};
var $div64 = function(x, y, returnRemainder) {
if (y.$high === 0 && y.$low === 0) {
$throwRuntimeError("integer divide by zero");
}
var s = 1;
var rs = 1;
var xHigh = x.$high;
var xLow = x.$low;
if (xHigh < 0) {
s = -1;
rs = -1;
xHigh = -xHigh;
if (xLow !== 0) {
xHigh--;
xLow = 4294967296 - xLow;
}
}
var yHigh = y.$high;
var yLow = y.$low;
if (y.$high < 0) {
s *= -1;
yHigh = -yHigh;
if (yLow !== 0) {
yHigh--;
yLow = 4294967296 - yLow;
}
}
var high = 0, low = 0, n = 0;
while (yHigh < 2147483648 && ((xHigh > yHigh) || (xHigh === yHigh && xLow > yLow))) {
yHigh = (yHigh << 1 | yLow >>> 31) >>> 0;
yLow = (yLow << 1) >>> 0;
n++;
}
for (var i = 0; i <= n; i++) {
high = high << 1 | low >>> 31;
low = (low << 1) >>> 0;
if ((xHigh > yHigh) || (xHigh === yHigh && xLow >= yLow)) {
xHigh = xHigh - yHigh;
xLow = xLow - yLow;
if (xLow < 0) {
xHigh--;
xLow += 4294967296;
}
low++;
if (low === 4294967296) {
high++;
low = 0;
}
}
yLow = (yLow >>> 1 | yHigh << (32 - 1)) >>> 0;
yHigh = yHigh >>> 1;
}
if (returnRemainder) {
return new x.constructor(xHigh * rs, xLow * rs);
}
return new x.constructor(high * s, low * s);
};
var $divComplex = function(n, d) {
var ninf = n.$real === Infinity || n.$real === -Infinity || n.$imag === Infinity || n.$imag === -Infinity;
var dinf = d.$real === Infinity || d.$real === -Infinity || d.$imag === Infinity || d.$imag === -Infinity;
var nnan = !ninf && (n.$real !== n.$real || n.$imag !== n.$imag);
var dnan = !dinf && (d.$real !== d.$real || d.$imag !== d.$imag);
if(nnan || dnan) {
return new n.constructor(NaN, NaN);
}
if (ninf && !dinf) {
return new n.constructor(Infinity, Infinity);
}
if (!ninf && dinf) {
return new n.constructor(0, 0);
}
if (d.$real === 0 && d.$imag === 0) {
if (n.$real === 0 && n.$imag === 0) {
return new n.constructor(NaN, NaN);
}
return new n.constructor(Infinity, Infinity);
}
var a = Math.abs(d.$real);
var b = Math.abs(d.$imag);
if (a <= b) {
var ratio = d.$real / d.$imag;
var denom = d.$real * ratio + d.$imag;
return new n.constructor((n.$real * ratio + n.$imag) / denom, (n.$imag * ratio - n.$real) / denom);
}
var ratio = d.$imag / d.$real;
var denom = d.$imag * ratio + d.$real;
return new n.constructor((n.$imag * ratio + n.$real) / denom, (n.$imag - n.$real * ratio) / denom);
};
var $kindBool = 1;
var $kindInt = 2;
var $kindInt8 = 3;
var $kindInt16 = 4;
var $kindInt32 = 5;
var $kindInt64 = 6;
var $kindUint = 7;
var $kindUint8 = 8;
var $kindUint16 = 9;
var $kindUint32 = 10;
var $kindUint64 = 11;
var $kindUintptr = 12;
var $kindFloat32 = 13;
var $kindFloat64 = 14;
var $kindComplex64 = 15;
var $kindComplex128 = 16;
var $kindArray = 17;
var $kindChan = 18;
var $kindFunc = 19;
var $kindInterface = 20;
var $kindMap = 21;
var $kindPtr = 22;
var $kindSlice = 23;
var $kindString = 24;
var $kindStruct = 25;
var $kindUnsafePointer = 26;
var $methodSynthesizers = [];
var $addMethodSynthesizer = function(f) {
if ($methodSynthesizers === null) {
f();
return;
}
$methodSynthesizers.push(f);
};
var $synthesizeMethods = function() {
$methodSynthesizers.forEach(function(f) { f(); });
$methodSynthesizers = null;
};
var $ifaceKeyFor = function(x) {
if (x === $ifaceNil) {
return 'nil';
}
var c = x.constructor;
return c.string + '$' + c.keyFor(x.$val);
};
var $identity = function(x) { return x; };
var $typeIDCounter = 0;
var $idKey = function(x) {
if (x.$id === undefined) {
$idCounter++;
x.$id = $idCounter;
}
return String(x.$id);
};
var $newType = function(size, kind, string, named, pkg, exported, constructor) {
var typ;
switch(kind) {
case $kindBool:
case $kindInt:
case $kindInt8:
case $kindInt16:
case $kindInt32:
case $kindUint:
case $kindUint8:
case $kindUint16:
case $kindUint32:
case $kindUintptr:
case $kindUnsafePointer:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.keyFor = $identity;
break;
case $kindString:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.keyFor = function(x) { return "$" + x; };
break;
case $kindFloat32:
case $kindFloat64:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.keyFor = function(x) { return $floatKey(x); };
break;
case $kindInt64:
typ = function(high, low) {
this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0;
this.$low = low >>> 0;
this.$val = this;
};
typ.keyFor = function(x) { return x.$high + "$" + x.$low; };
break;
case $kindUint64:
typ = function(high, low) {
this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0;
this.$low = low >>> 0;
this.$val = this;
};
typ.keyFor = function(x) { return x.$high + "$" + x.$low; };
break;
case $kindComplex64:
typ = function(real, imag) {
this.$real = $fround(real);
this.$imag = $fround(imag);
this.$val = this;
};
typ.keyFor = function(x) { return x.$real + "$" + x.$imag; };
break;
case $kindComplex128:
typ = function(real, imag) {
this.$real = real;
this.$imag = imag;
this.$val = this;
};
typ.keyFor = function(x) { return x.$real + "$" + x.$imag; };
break;
case $kindArray:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.ptr = $newType(4, $kindPtr, "*" + string, false, "", false, function(array) {
this.$get = function() { return array; };
this.$set = function(v) { typ.copy(this, v); };
this.$val = array;
});
typ.init = function(elem, len) {
typ.elem = elem;
typ.len = len;
typ.comparable = elem.comparable;
typ.keyFor = function(x) {
return Array.prototype.join.call($mapArray(x, function(e) {
return String(elem.keyFor(e)).replace(/\\/g, "\\\\").replace(/\$/g, "\\$");
}), "$");
};
typ.copy = function(dst, src) {
$copyArray(dst, src, 0, 0, src.length, elem);
};
typ.ptr.init(typ);
Object.defineProperty(typ.ptr.nil, "nilCheck", { get: $throwNilPointerError });
};
break;
case $kindChan:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.keyFor = $idKey;
typ.init = function(elem, sendOnly, recvOnly) {
typ.elem = elem;
typ.sendOnly = sendOnly;
typ.recvOnly = recvOnly;
};
break;
case $kindFunc:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.init = function(params, results, variadic) {
typ.params = params;
typ.results = results;
typ.variadic = variadic;
typ.comparable = false;
};
break;
case $kindInterface:
typ = { implementedBy: {}, missingMethodFor: {} };
typ.keyFor = $ifaceKeyFor;
typ.init = function(methods) {
typ.methods = methods;
methods.forEach(function(m) {
$ifaceNil[m.prop] = $throwNilPointerError;
});
};
break;
case $kindMap:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.init = function(key, elem) {
typ.key = key;
typ.elem = elem;
typ.comparable = false;
};
break;
case $kindPtr:
typ = constructor || function(getter, setter, target) {
this.$get = getter;
this.$set = setter;
this.$target = target;
this.$val = this;
};
typ.keyFor = $idKey;
typ.init = function(elem) {
typ.elem = elem;
typ.wrapped = (elem.kind === $kindArray);
typ.nil = new typ($throwNilPointerError, $throwNilPointerError);
};
break;
case $kindSlice:
typ = function(array) {
if (array.constructor !== typ.nativeArray) {
array = new typ.nativeArray(array);
}
this.$array = array;
this.$offset = 0;
this.$length = array.length;
this.$capacity = array.length;
this.$val = this;
};
typ.init = function(elem) {
typ.elem = elem;
typ.comparable = false;
typ.nativeArray = $nativeArray(elem.kind);
typ.nil = new typ([]);
};
break;
case $kindStruct:
typ = function(v) { this.$val = v; };
typ.wrapped = true;
typ.ptr = $newType(4, $kindPtr, "*" + string, false, "", exported, constructor);
typ.ptr.elem = typ;
typ.ptr.prototype.$get = function() { return this; };
typ.ptr.prototype.$set = function(v) { typ.copy(this, v); };
typ.init = function(pkgPath, fields) {
typ.pkgPath = pkgPath;
typ.fields = fields;
fields.forEach(function(f) {
if (!f.typ.comparable) {
typ.comparable = false;
}
});
typ.keyFor = function(x) {
var val = x.$val;
return $mapArray(fields, function(f) {
return String(f.typ.keyFor(val[f.prop])).replace(/\\/g, "\\\\").replace(/\$/g, "\\$");
}).join("$");
};
typ.copy = function(dst, src) {
for (var i = 0; i < fields.length; i++) {
var f = fields[i];
switch (f.typ.kind) {
case $kindArray:
case $kindStruct:
f.typ.copy(dst[f.prop], src[f.prop]);
continue;
default:
dst[f.prop] = src[f.prop];
continue;
}
}
};
/* nil value */
var properties = {};
fields.forEach(function(f) {
properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError };
});
typ.ptr.nil = Object.create(constructor.prototype, properties);
typ.ptr.nil.$val = typ.ptr.nil;
/* methods for embedded fields */
$addMethodSynthesizer(function() {
var synthesizeMethod = function(target, m, f) {
if (target.prototype[m.prop] !== undefined) { return; }
target.prototype[m.prop] = function() {
var v = this.$val[f.prop];
if (f.typ === $jsObjectPtr) {
v = new $jsObjectPtr(v);
}
if (v.$val === undefined) {
v = new f.typ(v);
}
return v[m.prop].apply(v, arguments);
};
};
fields.forEach(function(f) {
if (f.name === "") {
$methodSet(f.typ).forEach(function(m) {
synthesizeMethod(typ, m, f);
synthesizeMethod(typ.ptr, m, f);
});
$methodSet($ptrType(f.typ)).forEach(function(m) {
synthesizeMethod(typ.ptr, m, f);
});
}
});
});
};
break;
default:
$panic(new $String("invalid kind: " + kind));
}
switch (kind) {
case $kindBool:
case $kindMap:
typ.zero = function() { return false; };
break;
case $kindInt:
case $kindInt8:
case $kindInt16:
case $kindInt32:
case $kindUint:
case $kindUint8 :
case $kindUint16:
case $kindUint32:
case $kindUintptr:
case $kindUnsafePointer:
case $kindFloat32:
case $kindFloat64:
typ.zero = function() { return 0; };
break;
case $kindString:
typ.zero = function() { return ""; };
break;
case $kindInt64:
case $kindUint64:
case $kindComplex64:
case $kindComplex128:
var zero = new typ(0, 0);
typ.zero = function() { return zero; };
break;
case $kindPtr:
case $kindSlice:
typ.zero = function() { return typ.nil; };
break;
case $kindChan:
typ.zero = function() { return $chanNil; };
break;
case $kindFunc:
typ.zero = function() { return $throwNilPointerError; };
break;
case $kindInterface:
typ.zero = function() { return $ifaceNil; };
break;
case $kindArray:
typ.zero = function() {
var arrayClass = $nativeArray(typ.elem.kind);
if (arrayClass !== Array) {
return new arrayClass(typ.len);
}
var array = new Array(typ.len);
for (var i = 0; i < typ.len; i++) {
array[i] = typ.elem.zero();
}
return array;
};
break;
case $kindStruct:
typ.zero = function() { return new typ.ptr(); };
break;
default:
$panic(new $String("invalid kind: " + kind));
}
typ.id = $typeIDCounter;
$typeIDCounter++;
typ.size = size;
typ.kind = kind;
typ.string = string;
typ.named = named;
typ.pkg = pkg;
typ.exported = exported;
typ.methods = [];
typ.methodSetCache = null;
typ.comparable = true;
return typ;
};
var $methodSet = function(typ) {
if (typ.methodSetCache !== null) {
return typ.methodSetCache;
}
var base = {};
var isPtr = (typ.kind === $kindPtr);
if (isPtr && typ.elem.kind === $kindInterface) {
typ.methodSetCache = [];
return [];
}
var current = [{typ: isPtr ? typ.elem : typ, indirect: isPtr}];
var seen = {};
while (current.length > 0) {
var next = [];
var mset = [];
current.forEach(function(e) {
if (seen[e.typ.string]) {
return;
}
seen[e.typ.string] = true;
if (e.typ.named) {
mset = mset.concat(e.typ.methods);
if (e.indirect) {
mset = mset.concat($ptrType(e.typ).methods);
}
}
switch (e.typ.kind) {
case $kindStruct:
e.typ.fields.forEach(function(f) {
if (f.name === "") {
var fTyp = f.typ;
var fIsPtr = (fTyp.kind === $kindPtr);
next.push({typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr});
}
});
break;
case $kindInterface:
mset = mset.concat(e.typ.methods);
break;
}
});
mset.forEach(function(m) {
if (base[m.name] === undefined) {
base[m.name] = m;
}
});
current = next;
}
typ.methodSetCache = [];
Object.keys(base).sort().forEach(function(name) {
typ.methodSetCache.push(base[name]);
});
return typ.methodSetCache;
};
var $Bool = $newType( 1, $kindBool, "bool", true, "", false, null);
var $Int = $newType( 4, $kindInt, "int", true, "", false, null);
var $Int8 = $newType( 1, $kindInt8, "int8", true, "", false, null);
var $Int16 = $newType( 2, $kindInt16, "int16", true, "", false, null);
var $Int32 = $newType( 4, $kindInt32, "int32", true, "", false, null);
var $Int64 = $newType( 8, $kindInt64, "int64", true, "", false, null);
var $Uint = $newType( 4, $kindUint, "uint", true, "", false, null);
var $Uint8 = $newType( 1, $kindUint8, "uint8", true, "", false, null);
var $Uint16 = $newType( 2, $kindUint16, "uint16", true, "", false, null);
var $Uint32 = $newType( 4, $kindUint32, "uint32", true, "", false, null);
var $Uint64 = $newType( 8, $kindUint64, "uint64", true, "", false, null);
var $Uintptr = $newType( 4, $kindUintptr, "uintptr", true, "", false, null);
var $Float32 = $newType( 4, $kindFloat32, "float32", true, "", false, null);
var $Float64 = $newType( 8, $kindFloat64, "float64", true, "", false, null);
var $Complex64 = $newType( 8, $kindComplex64, "complex64", true, "", false, null);
var $Complex128 = $newType(16, $kindComplex128, "complex128", true, "", false, null);
var $String = $newType( 8, $kindString, "string", true, "", false, null);
var $UnsafePointer = $newType( 4, $kindUnsafePointer, "unsafe.Pointer", true, "", false, null);
var $nativeArray = function(elemKind) {
switch (elemKind) {
case $kindInt:
return Int32Array;
case $kindInt8:
return Int8Array;
case $kindInt16:
return Int16Array;
case $kindInt32:
return Int32Array;
case $kindUint:
return Uint32Array;
case $kindUint8:
return Uint8Array;
case $kindUint16:
return Uint16Array;
case $kindUint32:
return Uint32Array;
case $kindUintptr:
return Uint32Array;
case $kindFloat32:
return Float32Array;
case $kindFloat64:
return Float64Array;
default:
return Array;
}
};
var $toNativeArray = function(elemKind, array) {
var nativeArray = $nativeArray(elemKind);
if (nativeArray === Array) {
return array;
}
return new nativeArray(array);
};
var $arrayTypes = {};
var $arrayType = function(elem, len) {
var typeKey = elem.id + "$" + len;
var typ = $arrayTypes[typeKey];
if (typ === undefined) {
typ = $newType(12, $kindArray, "[" + len + "]" + elem.string, false, "", false, null);
$arrayTypes[typeKey] = typ;
typ.init(elem, len);
}
return typ;
};
var $chanType = function(elem, sendOnly, recvOnly) {
var string = (recvOnly ? "<-" : "") + "chan" + (sendOnly ? "<- " : " ") + elem.string;
var field = sendOnly ? "SendChan" : (recvOnly ? "RecvChan" : "Chan");
var typ = elem[field];
if (typ === undefined) {
typ = $newType(4, $kindChan, string, false, "", false, null);
elem[field] = typ;
typ.init(elem, sendOnly, recvOnly);
}
return typ;
};
var $Chan = function(elem, capacity) {
if (capacity < 0 || capacity > 2147483647) {
$throwRuntimeError("makechan: size out of range");
}
this.$elem = elem;
this.$capacity = capacity;
this.$buffer = [];
this.$sendQueue = [];
this.$recvQueue = [];
this.$closed = false;
};
var $chanNil = new $Chan(null, 0);
$chanNil.$sendQueue = $chanNil.$recvQueue = { length: 0, push: function() {}, shift: function() { return undefined; }, indexOf: function() { return -1; } };
var $funcTypes = {};
var $funcType = function(params, results, variadic) {
var typeKey = $mapArray(params, function(p) { return p.id; }).join(",") + "$" + $mapArray(results, function(r) { return r.id; }).join(",") + "$" + variadic;
var typ = $funcTypes[typeKey];
if (typ === undefined) {
var paramTypes = $mapArray(params, function(p) { return p.string; });
if (variadic) {
paramTypes[paramTypes.length - 1] = "..." + paramTypes[paramTypes.length - 1].substr(2);
}
var string = "func(" + paramTypes.join(", ") + ")";
if (results.length === 1) {
string += " " + results[0].string;
} else if (results.length > 1) {
string += " (" + $mapArray(results, function(r) { return r.string; }).join(", ") + ")";
}
typ = $newType(4, $kindFunc, string, false, "", false, null);
$funcTypes[typeKey] = typ;
typ.init(params, results, variadic);
}
return typ;
};
var $interfaceTypes = {};
var $interfaceType = function(methods) {
var typeKey = $mapArray(methods, function(m) { return m.pkg + "," + m.name + "," + m.typ.id; }).join("$");
var typ = $interfaceTypes[typeKey];
if (typ === undefined) {
var string = "interface {}";
if (methods.length !== 0) {
string = "interface { " + $mapArray(methods, function(m) {
return (m.pkg !== "" ? m.pkg + "." : "") + m.name + m.typ.string.substr(4);
}).join("; ") + " }";
}
typ = $newType(8, $kindInterface, string, false, "", false, null);
$interfaceTypes[typeKey] = typ;
typ.init(methods);
}
return typ;
};
var $emptyInterface = $interfaceType([]);
var $ifaceNil = {};
var $error = $newType(8, $kindInterface, "error", true, "", false, null);
$error.init([{prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}]);
var $mapTypes = {};
var $mapType = function(key, elem) {
var typeKey = key.id + "$" + elem.id;
var typ = $mapTypes[typeKey];
if (typ === undefined) {
typ = $newType(4, $kindMap, "map[" + key.string + "]" + elem.string, false, "", false, null);
$mapTypes[typeKey] = typ;
typ.init(key, elem);
}
return typ;
};
var $makeMap = function(keyForFunc, entries) {
var m = {};
for (var i = 0; i < entries.length; i++) {
var e = entries[i];
m[keyForFunc(e.k)] = e;
}
return m;
};
var $ptrType = function(elem) {
var typ = elem.ptr;
if (typ === undefined) {
typ = $newType(4, $kindPtr, "*" + elem.string, false, "", elem.exported, null);
elem.ptr = typ;
typ.init(elem);
}
return typ;
};
var $newDataPointer = function(data, constructor) {
if (constructor.elem.kind === $kindStruct) {
return data;
}
return new constructor(function() { return data; }, function(v) { data = v; });
};
var $indexPtr = function(array, index, constructor) {
array.$ptr = array.$ptr || {};
return array.$ptr[index] || (array.$ptr[index] = new constructor(function() { return array[index]; }, function(v) { array[index] = v; }));
};
var $sliceType = function(elem) {
var typ = elem.slice;
if (typ === undefined) {
typ = $newType(12, $kindSlice, "[]" + elem.string, false, "", false, null);
elem.slice = typ;
typ.init(elem);
}
return typ;
};
var $makeSlice = function(typ, length, capacity) {
capacity = capacity || length;
if (length < 0 || length > 2147483647) {
$throwRuntimeError("makeslice: len out of range");
}
if (capacity < 0 || capacity < length || capacity > 2147483647) {
$throwRuntimeError("makeslice: cap out of range");
}
var array = new typ.nativeArray(capacity);
if (typ.nativeArray === Array) {
for (var i = 0; i < capacity; i++) {
array[i] = typ.elem.zero();
}
}
var slice = new typ(array);
slice.$length = length;
return slice;
};
var $structTypes = {};
var $structType = function(pkgPath, fields) {
var typeKey = $mapArray(fields, function(f) { return f.name + "," + f.typ.id + "," + f.tag; }).join("$");
var typ = $structTypes[typeKey];
if (typ === undefined) {
var string = "struct { " + $mapArray(fields, function(f) {
return f.name + " " + f.typ.string + (f.tag !== "" ? (" \"" + f.tag.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\"") : "");
}).join("; ") + " }";
if (fields.length === 0) {
string = "struct {}";
}
typ = $newType(0, $kindStruct, string, false, "", false, function() {
this.$val = this;
for (var i = 0; i < fields.length; i++) {
var f = fields[i];
var arg = arguments[i];
this[f.prop] = arg !== undefined ? arg : f.typ.zero();
}
});
$structTypes[typeKey] = typ;
typ.init(pkgPath, fields);
}
return typ;
};
var $assertType = function(value, type, returnTuple) {
var isInterface = (type.kind === $kindInterface), ok, missingMethod = "";
if (value === $ifaceNil) {
ok = false;
} else if (!isInterface) {
ok = value.constructor === type;
} else {
var valueTypeString = value.constructor.string;
ok = type.implementedBy[valueTypeString];
if (ok === undefined) {
ok = true;
var valueMethodSet = $methodSet(value.constructor);
var interfaceMethods = type.methods;
for (var i = 0; i < interfaceMethods.length; i++) {
var tm = interfaceMethods[i];
var found = false;
for (var j = 0; j < valueMethodSet.length; j++) {
var vm = valueMethodSet[j];
if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) {
found = true;
break;
}
}
if (!found) {
ok = false;
type.missingMethodFor[valueTypeString] = tm.name;
break;
}
}
type.implementedBy[valueTypeString] = ok;
}
if (!ok) {
missingMethod = type.missingMethodFor[valueTypeString];
}
}
if (!ok) {
if (returnTuple) {
return [type.zero(), false];
}
$panic(new $packages["runtime"].TypeAssertionError.ptr("", (value === $ifaceNil ? "" : value.constructor.string), type.string, missingMethod));
}
if (!isInterface) {
value = value.$val;
}
if (type === $jsObjectPtr) {
value = value.object;
}
return returnTuple ? [value, true] : value;
};
var $stackDepthOffset = 0;
var $getStackDepth = function() {
var err = new Error();
if (err.stack === undefined) {
return undefined;
}
return $stackDepthOffset + err.stack.split("\n").length;
};
var $panicStackDepth = null, $panicValue;
var $callDeferred = function(deferred, jsErr, fromPanic) {
if (!fromPanic && deferred !== null && deferred.index >= $curGoroutine.deferStack.length) {
throw jsErr;
}
if (jsErr !== null) {
var newErr = null;
try {
$curGoroutine.deferStack.push(deferred);
$panic(new $jsErrorPtr(jsErr));
} catch (err) {
newErr = err;
}
$curGoroutine.deferStack.pop();
$callDeferred(deferred, newErr);
return;
}
if ($curGoroutine.asleep) {
return;
}
$stackDepthOffset--;
var outerPanicStackDepth = $panicStackDepth;
var outerPanicValue = $panicValue;
var localPanicValue = $curGoroutine.panicStack.pop();
if (localPanicValue !== undefined) {
$panicStackDepth = $getStackDepth();
$panicValue = localPanicValue;
}
try {
while (true) {
if (deferred === null) {
deferred = $curGoroutine.deferStack[$curGoroutine.deferStack.length - 1];
if (deferred === undefined) {
/* The panic reached the top of the stack. Clear it and throw it as a JavaScript error. */
$panicStackDepth = null;
if (localPanicValue.Object instanceof Error) {
throw localPanicValue.Object;
}
var msg;
if (localPanicValue.constructor === $String) {
msg = localPanicValue.$val;
} else if (localPanicValue.Error !== undefined) {
msg = localPanicValue.Error();
} else if (localPanicValue.String !== undefined) {
msg = localPanicValue.String();
} else {
msg = localPanicValue;
}
throw new Error(msg);
}
}
var call = deferred.pop();
if (call === undefined) {
$curGoroutine.deferStack.pop();
if (localPanicValue !== undefined) {
deferred = null;
continue;
}
return;
}
var r = call[0].apply(call[2], call[1]);
if (r && r.$blk !== undefined) {
deferred.push([r.$blk, [], r]);
if (fromPanic) {
throw null;
}
return;
}
if (localPanicValue !== undefined && $panicStackDepth === null) {
throw null; /* error was recovered */
}
}
} finally {
if (localPanicValue !== undefined) {
if ($panicStackDepth !== null) {
$curGoroutine.panicStack.push(localPanicValue);
}
$panicStackDepth = outerPanicStackDepth;
$panicValue = outerPanicValue;
}
$stackDepthOffset++;
}
};
var $panic = function(value) {
$curGoroutine.panicStack.push(value);
$callDeferred(null, null, true);
};
var $recover = function() {
if ($panicStackDepth === null || ($panicStackDepth !== undefined && $panicStackDepth !== $getStackDepth() - 2)) {
return $ifaceNil;
}
$panicStackDepth = null;
return $panicValue;
};
var $throw = function(err) { throw err; };
var $noGoroutine = { asleep: false, exit: false, deferStack: [], panicStack: [] };
var $curGoroutine = $noGoroutine, $totalGoroutines = 0, $awakeGoroutines = 0, $checkForDeadlock = true;
var $mainFinished = false;
var $go = function(fun, args, direct) {
$totalGoroutines++;
$awakeGoroutines++;
var $goroutine = function() {
try {
$curGoroutine = $goroutine;
var r = fun.apply(undefined, args);
if (r && r.$blk !== undefined) {
fun = function() { return r.$blk(); };
args = [];
return;
}
$goroutine.exit = true;
} catch (err) {
if (!$goroutine.exit) {
throw err;
}
} finally {
$curGoroutine = $noGoroutine;
if ($goroutine.exit) { /* also set by runtime.Goexit() */
$totalGoroutines--;
$goroutine.asleep = true;
}
if ($goroutine.asleep) {
$awakeGoroutines--;
if (!$mainFinished && $awakeGoroutines === 0 && $checkForDeadlock) {
console.error("fatal error: all goroutines are asleep - deadlock!");
if ($global.process !== undefined) {
$global.process.exit(2);
}
}
}
}
};
$goroutine.asleep = false;
$goroutine.exit = false;
$goroutine.deferStack = [];
$goroutine.panicStack = [];
$schedule($goroutine);
};
var $scheduled = [];
var $runScheduled = function() {
try {
var r;
while ((r = $scheduled.shift()) !== undefined) {
r();
}
} finally {
if ($scheduled.length > 0) {
setTimeout($runScheduled, 0);
}
}
};
var $schedule = function(goroutine) {
if (goroutine.asleep) {
goroutine.asleep = false;
$awakeGoroutines++;
}
$scheduled.push(goroutine);
if ($curGoroutine === $noGoroutine) {
$runScheduled();
}
};
var $setTimeout = function(f, t) {
$awakeGoroutines++;
return setTimeout(function() {
$awakeGoroutines--;
f();
}, t);
};
var $block = function() {
if ($curGoroutine === $noGoroutine) {
$throwRuntimeError("cannot block in JavaScript callback, fix by wrapping code in goroutine");
}
$curGoroutine.asleep = true;
};
var $send = function(chan, value) {
if (chan.$closed) {
$throwRuntimeError("send on closed channel");
}
var queuedRecv = chan.$recvQueue.shift();
if (queuedRecv !== undefined) {
queuedRecv([value, true]);
return;
}
if (chan.$buffer.length < chan.$capacity) {
chan.$buffer.push(value);
return;
}
var thisGoroutine = $curGoroutine;
var closedDuringSend;
chan.$sendQueue.push(function(closed) {
closedDuringSend = closed;
$schedule(thisGoroutine);
return value;
});
$block();
return {
$blk: function() {
if (closedDuringSend) {
$throwRuntimeError("send on closed channel");
}
}
};
};
var $recv = function(chan) {
var queuedSend = chan.$sendQueue.shift();
if (queuedSend !== undefined) {
chan.$buffer.push(queuedSend(false));
}
var bufferedValue = chan.$buffer.shift();
if (bufferedValue !== undefined) {
return [bufferedValue, true];
}
if (chan.$closed) {
return [chan.$elem.zero(), false];
}
var thisGoroutine = $curGoroutine;
var f = { $blk: function() { return this.value; } };
var queueEntry = function(v) {
f.value = v;
$schedule(thisGoroutine);
};
chan.$recvQueue.push(queueEntry);
$block();
return f;
};
var $close = function(chan) {
if (chan.$closed) {
$throwRuntimeError("close of closed channel");
}
chan.$closed = true;
while (true) {
var queuedSend = chan.$sendQueue.shift();
if (queuedSend === undefined) {
break;
}
queuedSend(true); /* will panic */
}
while (true) {
var queuedRecv = chan.$recvQueue.shift();
if (queuedRecv === undefined) {
break;
}
queuedRecv([chan.$elem.zero(), false]);
}
};
var $select = function(comms) {
var ready = [];
var selection = -1;
for (var i = 0; i < comms.length; i++) {
var comm = comms[i];
var chan = comm[0];
switch (comm.length) {
case 0: /* default */
selection = i;
break;
case 1: /* recv */
if (chan.$sendQueue.length !== 0 || chan.$buffer.length !== 0 || chan.$closed) {
ready.push(i);
}
break;
case 2: /* send */
if (chan.$closed) {
$throwRuntimeError("send on closed channel");
}
if (chan.$recvQueue.length !== 0 || chan.$buffer.length < chan.$capacity) {
ready.push(i);
}
break;
}
}
if (ready.length !== 0) {
selection = ready[Math.floor(Math.random() * ready.length)];
}
if (selection !== -1) {
var comm = comms[selection];
switch (comm.length) {
case 0: /* default */
return [selection];
case 1: /* recv */
return [selection, $recv(comm[0])];
case 2: /* send */
$send(comm[0], comm[1]);
return [selection];
}
}
var entries = [];
var thisGoroutine = $curGoroutine;
var f = { $blk: function() { return this.selection; } };
var removeFromQueues = function() {
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var queue = entry[0];
var index = queue.indexOf(entry[1]);
if (index !== -1) {
queue.splice(index, 1);
}
}
};
for (var i = 0; i < comms.length; i++) {
(function(i) {
var comm = comms[i];
switch (comm.length) {
case 1: /* recv */
var queueEntry = function(value) {
f.selection = [i, value];
removeFromQueues();
$schedule(thisGoroutine);
};
entries.push([comm[0].$recvQueue, queueEntry]);
comm[0].$recvQueue.push(queueEntry);
break;
case 2: /* send */
var queueEntry = function() {
if (comm[0].$closed) {
$throwRuntimeError("send on closed channel");
}
f.selection = [i];
removeFromQueues();
$schedule(thisGoroutine);
return comm[1];
};
entries.push([comm[0].$sendQueue, queueEntry]);
comm[0].$sendQueue.push(queueEntry);
break;
}
})(i);
}
$block();
return f;
};
var $jsObjectPtr, $jsErrorPtr;
var $needsExternalization = function(t) {
switch (t.kind) {
case $kindBool:
case $kindInt:
case $kindInt8:
case $kindInt16:
case $kindInt32:
case $kindUint:
case $kindUint8:
case $kindUint16:
case $kindUint32:
case $kindUintptr:
case $kindFloat32:
case $kindFloat64:
return false;
default:
return t !== $jsObjectPtr;
}
};
var $externalize = function(v, t) {
if (t === $jsObjectPtr) {
return v;
}
switch (t.kind) {
case $kindBool:
case $kindInt:
case $kindInt8:
case $kindInt16:
case $kindInt32:
case $kindUint:
case $kindUint8:
case $kindUint16:
case $kindUint32:
case $kindUintptr:
case $kindFloat32:
case $kindFloat64:
return v;
case $kindInt64:
case $kindUint64:
return $flatten64(v);
case $kindArray:
if ($needsExternalization(t.elem)) {
return $mapArray(v, function(e) { return $externalize(e, t.elem); });
}
return v;
case $kindFunc:
return $externalizeFunction(v, t, false);
case $kindInterface:
if (v === $ifaceNil) {
return null;
}
if (v.constructor === $jsObjectPtr) {
return v.$val.object;
}
return $externalize(v.$val, v.constructor);
case $kindMap:
var m = {};
var keys = $keys(v);
for (var i = 0; i < keys.length; i++) {
var entry = v[keys[i]];
m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem);
}
return m;
case $kindPtr:
if (v === t.nil) {
return null;
}
return $externalize(v.$get(), t.elem);
case $kindSlice:
if ($needsExternalization(t.elem)) {
return $mapArray($sliceToArray(v), function(e) { return $externalize(e, t.elem); });
}
return $sliceToArray(v);
case $kindString:
if (v.search(/^[\x00-\x7F]*$/) !== -1) {
return v;
}
var s = "", r;
for (var i = 0; i < v.length; i += r[1]) {
r = $decodeRune(v, i);
var c = r[0];
if (c > 0xFFFF) {
var h = Math.floor((c - 0x10000) / 0x400) + 0xD800;
var l = (c - 0x10000) % 0x400 + 0xDC00;
s += String.fromCharCode(h, l);
continue;
}
s += String.fromCharCode(c);
}
return s;
case $kindStruct:
var timePkg = $packages["time"];
if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) {
var milli = $div64(v.UnixNano(), new $Int64(0, 1000000));
return new Date($flatten64(milli));
}
var noJsObject = {};
var searchJsObject = function(v, t) {
if (t === $jsObjectPtr) {
return v;
}
switch (t.kind) {
case $kindPtr:
if (v === t.nil) {
return noJsObject;
}
return searchJsObject(v.$get(), t.elem);
case $kindStruct:
var f = t.fields[0];
return searchJsObject(v[f.prop], f.typ);
case $kindInterface:
return searchJsObject(v.$val, v.constructor);
default:
return noJsObject;
}
};
var o = searchJsObject(v, t);
if (o !== noJsObject) {
return o;
}
o = {};
for (var i = 0; i < t.fields.length; i++) {
var f = t.fields[i];
if (!f.exported) {
continue;
}
o[f.name] = $externalize(v[f.prop], f.typ);
}
return o;
}
$throwRuntimeError("cannot externalize " + t.string);
};
var $externalizeFunction = function(v, t, passThis) {
if (v === $throwNilPointerError) {
return null;
}
if (v.$externalizeWrapper === undefined) {
$checkForDeadlock = false;
v.$externalizeWrapper = function() {
var args = [];
for (var i = 0; i < t.params.length; i++) {
if (t.variadic && i === t.params.length - 1) {
var vt = t.params[i].elem, varargs = [];
for (var j = i; j < arguments.length; j++) {
varargs.push($internalize(arguments[j], vt));
}
args.push(new (t.params[i])(varargs));
break;
}
args.push($internalize(arguments[i], t.params[i]));
}
var canBlock = $curGoroutine.canBlock;
$curGoroutine.canBlock = false;
try {
var result = v.apply(passThis ? this : undefined, args);
} finally {
$curGoroutine.canBlock = canBlock;
}
switch (t.results.length) {
case 0:
return;
case 1:
return $externalize(result, t.results[0]);
default:
for (var i = 0; i < t.results.length; i++) {
result[i] = $externalize(result[i], t.results[i]);
}
return result;
}
};
}
return v.$externalizeWrapper;
};
var $internalize = function(v, t, recv) {
if (t === $jsObjectPtr) {
return v;
}
if (t === $jsObjectPtr.elem) {
$throwRuntimeError("cannot internalize js.Object, use *js.Object instead");
}
if (v && v.__internal_object__ !== undefined) {
return $assertType(v.__internal_object__, t, false);
}
var timePkg = $packages["time"];
if (timePkg !== undefined && t === timePkg.Time) {
if (!(v !== null && v !== undefined && v.constructor === Date)) {
$throwRuntimeError("cannot internalize time.Time from " + typeof v + ", must be Date");
}
return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000));
}
switch (t.kind) {
case $kindBool:
return !!v;
case $kindInt:
return parseInt(v);
case $kindInt8:
return parseInt(v) << 24 >> 24;
case $kindInt16:
return parseInt(v) << 16 >> 16;
case $kindInt32:
return parseInt(v) >> 0;
case $kindUint:
return parseInt(v);
case $kindUint8:
return parseInt(v) << 24 >>> 24;
case $kindUint16:
return parseInt(v) << 16 >>> 16;
case $kindUint32:
case $kindUintptr:
return parseInt(v) >>> 0;
case $kindInt64:
case $kindUint64:
return new t(0, v);
case $kindFloat32:
case $kindFloat64:
return parseFloat(v);
case $kindArray:
if (v.length !== t.len) {
$throwRuntimeError("got array with wrong size from JavaScript native");
}
return $mapArray(v, function(e) { return $internalize(e, t.elem); });
case $kindFunc:
return function() {
var args = [];
for (var i = 0; i < t.params.length; i++) {
if (t.variadic && i === t.params.length - 1) {
var vt = t.params[i].elem, varargs = arguments[i];
for (var j = 0; j < varargs.$length; j++) {
args.push($externalize(varargs.$array[varargs.$offset + j], vt));
}
break;
}
args.push($externalize(arguments[i], t.params[i]));
}
var result = v.apply(recv, args);
switch (t.results.length) {
case 0:
return;
case 1:
return $internalize(result, t.results[0]);
default:
for (var i = 0; i < t.results.length; i++) {
result[i] = $internalize(result[i], t.results[i]);
}
return result;
}
};
case $kindInterface:
if (t.methods.length !== 0) {
$throwRuntimeError("cannot internalize " + t.string);
}
if (v === null) {
return $ifaceNil;
}
if (v === undefined) {
return new $jsObjectPtr(undefined);
}
switch (v.constructor) {
case Int8Array:
return new ($sliceType($Int8))(v);
case Int16Array:
return new ($sliceType($Int16))(v);
case Int32Array:
return new ($sliceType($Int))(v);
case Uint8Array:
return new ($sliceType($Uint8))(v);
case Uint16Array:
return new ($sliceType($Uint16))(v);
case Uint32Array:
return new ($sliceType($Uint))(v);
case Float32Array:
return new ($sliceType($Float32))(v);
case Float64Array:
return new ($sliceType($Float64))(v);
case Array:
return $internalize(v, $sliceType($emptyInterface));
case Boolean:
return new $Bool(!!v);
case Date:
if (timePkg === undefined) {
/* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */
return new $jsObjectPtr(v);
}
return new timePkg.Time($internalize(v, timePkg.Time));
case Function:
var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true);
return new funcType($internalize(v, funcType));
case Number:
return new $Float64(parseFloat(v));
case String:
return new $String($internalize(v, $String));
default:
if ($global.Node && v instanceof $global.Node) {
return new $jsObjectPtr(v);
}
var mapType = $mapType($String, $emptyInterface);
return new mapType($internalize(v, mapType));
}
case $kindMap:
var m = {};
var keys = $keys(v);
for (var i = 0; i < keys.length; i++) {
var k = $internalize(keys[i], t.key);
m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) };
}
return m;
case $kindPtr:
if (t.elem.kind === $kindStruct) {
return $internalize(v, t.elem);
}
case $kindSlice:
return new t($mapArray(v, function(e) { return $internalize(e, t.elem); }));
case $kindString:
v = String(v);
if (v.search(/^[\x00-\x7F]*$/) !== -1) {
return v;
}
var s = "";
var i = 0;
while (i < v.length) {
var h = v.charCodeAt(i);
if (0xD800 <= h && h <= 0xDBFF) {
var l = v.charCodeAt(i + 1);
var c = (h - 0xD800) * 0x400 + l - 0xDC00 + 0x10000;
s += $encodeRune(c);
i += 2;
continue;
}
s += $encodeRune(h);
i++;
}
return s;
case $kindStruct:
var noJsObject = {};
var searchJsObject = function(t) {
if (t === $jsObjectPtr) {
return v;
}
if (t === $jsObjectPtr.elem) {
$throwRuntimeError("cannot internalize js.Object, use *js.Object instead");
}
switch (t.kind) {
case $kindPtr:
return searchJsObject(t.elem);
case $kindStruct:
var f = t.fields[0];
var o = searchJsObject(f.typ);
if (o !== noJsObject) {
var n = new t.ptr();
n[f.prop] = o;
return n;
}
return noJsObject;
default:
return noJsObject;
}
};
var o = searchJsObject(t);
if (o !== noJsObject) {
return o;
}
}
$throwRuntimeError("cannot internalize " + t.string);
};
$packages["github.com/gopherjs/gopherjs/js"] = (function() {
var $pkg = {}, $init, Object, Error, sliceType, ptrType, ptrType$1, init;
Object = $pkg.Object = $newType(0, $kindStruct, "js.Object", true, "github.com/gopherjs/gopherjs/js", true, function(object_) {
this.$val = this;
if (arguments.length === 0) {
this.object = null;
return;
}
this.object = object_;
});
Error = $pkg.Error = $newType(0, $kindStruct, "js.Error", true, "github.com/gopherjs/gopherjs/js", true, function(Object_) {
this.$val = this;
if (arguments.length === 0) {
this.Object = null;
return;
}
this.Object = Object_;
});
sliceType = $sliceType($emptyInterface);
ptrType = $ptrType(Object);
ptrType$1 = $ptrType(Error);
Object.ptr.prototype.Get = function(key) {
var $ptr, key, o;
o = this;
return o.object[$externalize(key, $String)];
};
Object.prototype.Get = function(key) { return this.$val.Get(key); };
Object.ptr.prototype.Set = function(key, value) {
var $ptr, key, o, value;
o = this;
o.object[$externalize(key, $String)] = $externalize(value, $emptyInterface);
};
Object.prototype.Set = function(key, value) { return this.$val.Set(key, value); };
Object.ptr.prototype.Delete = function(key) {
var $ptr, key, o;
o = this;
delete o.object[$externalize(key, $String)];
};
Object.prototype.Delete = function(key) { return this.$val.Delete(key); };
Object.ptr.prototype.Length = function() {
var $ptr, o;
o = this;
return $parseInt(o.object.length);
};
Object.prototype.Length = function() { return this.$val.Length(); };
Object.ptr.prototype.Index = function(i) {
var $ptr, i, o;
o = this;
return o.object[i];
};
Object.prototype.Index = function(i) { return this.$val.Index(i); };
Object.ptr.prototype.SetIndex = function(i, value) {
var $ptr, i, o, value;
o = this;
o.object[i] = $externalize(value, $emptyInterface);
};
Object.prototype.SetIndex = function(i, value) { return this.$val.SetIndex(i, value); };
Object.ptr.prototype.Call = function(name, args) {
var $ptr, args, name, o, obj;
o = this;
return (obj = o.object, obj[$externalize(name, $String)].apply(obj, $externalize(args, sliceType)));
};
Object.prototype.Call = function(name, args) { return this.$val.Call(name, args); };
Object.ptr.prototype.Invoke = function(args) {
var $ptr, args, o;
o = this;
return o.object.apply(undefined, $externalize(args, sliceType));
};
Object.prototype.Invoke = function(args) { return this.$val.Invoke(args); };
Object.ptr.prototype.New = function(args) {
var $ptr, args, o;
o = this;
return new ($global.Function.prototype.bind.apply(o.object, [undefined].concat($externalize(args, sliceType))));
};
Object.prototype.New = function(args) { return this.$val.New(args); };
Object.ptr.prototype.Bool = function() {
var $ptr, o;
o = this;
return !!(o.object);
};
Object.prototype.Bool = function() { return this.$val.Bool(); };
Object.ptr.prototype.String = function() {
var $ptr, o;
o = this;
return $internalize(o.object, $String);
};
Object.prototype.String = function() { return this.$val.String(); };
Object.ptr.prototype.Int = function() {
var $ptr, o;
o = this;
return $parseInt(o.object) >> 0;
};
Object.prototype.Int = function() { return this.$val.Int(); };
Object.ptr.prototype.Int64 = function() {
var $ptr, o;
o = this;
return $internalize(o.object, $Int64);
};
Object.prototype.Int64 = function() { return this.$val.Int64(); };
Object.ptr.prototype.Uint64 = function() {
var $ptr, o;
o = this;
return $internalize(o.object, $Uint64);
};
Object.prototype.Uint64 = function() { return this.$val.Uint64(); };
Object.ptr.prototype.Float = function() {
var $ptr, o;
o = this;
return $parseFloat(o.object);
};
Object.prototype.Float = function() { return this.$val.Float(); };
Object.ptr.prototype.Interface = function() {
var $ptr, o;
o = this;
return $internalize(o.object, $emptyInterface);
};
Object.prototype.Interface = function() { return this.$val.Interface(); };
Object.ptr.prototype.Unsafe = function() {
var $ptr, o;
o = this;
return o.object;
};
Object.prototype.Unsafe = function() { return this.$val.Unsafe(); };
Error.ptr.prototype.Error = function() {
var $ptr, err;
err = this;
return "JavaScript error: " + $internalize(err.Object.message, $String);
};
Error.prototype.Error = function() { return this.$val.Error(); };
Error.ptr.prototype.Stack = function() {
var $ptr, err;
err = this;
return $internalize(err.Object.stack, $String);
};
Error.prototype.Stack = function() { return this.$val.Stack(); };
init = function() {
var $ptr, e;
e = new Error.ptr(null);
$unused(e);
};
ptrType.methods = [{prop: "Get", name: "Get", pkg: "", typ: $funcType([$String], [ptrType], false)}, {prop: "Set", name: "Set", pkg: "", typ: $funcType([$String, $emptyInterface], [], false)}, {prop: "Delete", name: "Delete", pkg: "", typ: $funcType([$String], [], false)}, {prop: "Length", name: "Length", pkg: "", typ: $funcType([], [$Int], false)}, {prop: "Index", name: "Index", pkg: "", typ: $funcType([$Int], [ptrType], false)}, {prop: "SetIndex", name: "SetIndex", pkg: "", typ: $funcType([$Int, $emptyInterface], [], false)}, {prop: "Call", name: "Call", pkg: "", typ: $funcType([$String, sliceType], [ptrType], true)}, {prop: "Invoke", name: "Invoke", pkg: "", typ: $funcType([sliceType], [ptrType], true)}, {prop: "New", name: "New", pkg: "", typ: $funcType([sliceType], [ptrType], true)}, {prop: "Bool", name: "Bool", pkg: "", typ: $funcType([], [$Bool], false)}, {prop: "String", name: "String", pkg: "", typ: $funcType([], [$String], false)}, {prop: "Int", name: "Int", pkg: "", typ: $funcType([], [$Int], false)}, {prop: "Int64", name: "Int64", pkg: "", typ: $funcType([], [$Int64], false)}, {prop: "Uint64", name: "Uint64", pkg: "", typ: $funcType([], [$Uint64], false)}, {prop: "Float", name: "Float", pkg: "", typ: $funcType([], [$Float64], false)}, {prop: "Interface", name: "Interface", pkg: "", typ: $funcType([], [$emptyInterface], false)}, {prop: "Unsafe", name: "Unsafe", pkg: "", typ: $funcType([], [$Uintptr], false)}];
ptrType$1.methods = [{prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}, {prop: "Stack", name: "Stack", pkg: "", typ: $funcType([], [$String], false)}];
Object.init("github.com/gopherjs/gopherjs/js", [{prop: "object", name: "object", exported: false, typ: ptrType, tag: ""}]);
Error.init("", [{prop: "Object", name: "", exported: true, typ: ptrType, tag: ""}]);
$init = function() {
$pkg.$init = function() {};
/* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
init();
/* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f;
};
$pkg.$init = $init;
return $pkg;
})();
$packages["runtime/internal/sys"] = (function() {
var $pkg = {}, $init;
$init = function() {
$pkg.$init = function() {};
/* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
/* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f;
};
$pkg.$init = $init;
return $pkg;
})();
$packages["runtime"] = (function() {
var $pkg = {}, $init, js, sys, TypeAssertionError, errorString, ptrType$3, init;
js = $packages["github.com/gopherjs/gopherjs/js"];
sys = $packages["runtime/internal/sys"];
TypeAssertionError = $pkg.TypeAssertionError = $newType(0, $kindStruct, "runtime.TypeAssertionError", true, "runtime", true, function(interfaceString_, concreteString_, assertedString_, missingMethod_) {
this.$val = this;
if (arguments.length === 0) {
this.interfaceString = "";
this.concreteString = "";
this.assertedString = "";
this.missingMethod = "";
return;
}
this.interfaceString = interfaceString_;
this.concreteString = concreteString_;
this.assertedString = assertedString_;
this.missingMethod = missingMethod_;
});
errorString = $pkg.errorString = $newType(8, $kindString, "runtime.errorString", true, "runtime", false, null);
ptrType$3 = $ptrType(TypeAssertionError);
init = function() {
var $ptr, e, jsPkg;
jsPkg = $packages[$externalize("github.com/gopherjs/gopherjs/js", $String)];
$jsObjectPtr = jsPkg.Object.ptr;
$jsErrorPtr = jsPkg.Error.ptr;
$throwRuntimeError = (function(msg) {
var $ptr, msg;
$panic(new errorString(msg));
});
e = $ifaceNil;
e = new TypeAssertionError.ptr("", "", "", "");
$unused(e);
};
TypeAssertionError.ptr.prototype.RuntimeError = function() {
var $ptr;
};
TypeAssertionError.prototype.RuntimeError = function() { return this.$val.RuntimeError(); };
TypeAssertionError.ptr.prototype.Error = function() {
var $ptr, e, inter;
e = this;
inter = e.interfaceString;
if (inter === "") {
inter = "interface";
}
if (e.concreteString === "") {
return "interface conversion: " + inter + " is nil, not " + e.assertedString;
}
if (e.missingMethod === "") {
return "interface conversion: " + inter + " is " + e.concreteString + ", not " + e.assertedString;
}
return "interface conversion: " + e.concreteString + " is not " + e.assertedString + ": missing method " + e.missingMethod;
};
TypeAssertionError.prototype.Error = function() { return this.$val.Error(); };
errorString.prototype.RuntimeError = function() {
var $ptr, e;
e = this.$val;
};
$ptrType(errorString).prototype.RuntimeError = function() { return new errorString(this.$get()).RuntimeError(); };
errorString.prototype.Error = function() {
var $ptr, e;
e = this.$val;
return "runtime error: " + e;
};
$ptrType(errorString).prototype.Error = function() { return new errorString(this.$get()).Error(); };
ptrType$3.methods = [{prop: "RuntimeError", name: "RuntimeError", pkg: "", typ: $funcType([], [], false)}, {prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}];
errorString.methods = [{prop: "RuntimeError", name: "RuntimeError", pkg: "", typ: $funcType([], [], false)}, {prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}];
TypeAssertionError.init("runtime", [{prop: "interfaceString", name: "interfaceString", exported: false, typ: $String, tag: ""}, {prop: "concreteString", name: "concreteString", exported: false, typ: $String, tag: ""}, {prop: "assertedString", name: "assertedString", exported: false, typ: $String, tag: ""}, {prop: "missingMethod", name: "missingMethod", exported: false, typ: $String, tag: ""}]);
$init = function() {
$pkg.$init = function() {};
/* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
$r = js.$init(); /* */ $s = 1; case 1: if($c) { $c = false; $r = $r.$blk(); } if ($r && $r.$blk !== undefined) { break s; }
$r = sys.$init(); /* */ $s = 2; case 2: if($c) { $c = false; $r = $r.$blk(); } if ($r && $r.$blk !== undefined) { break s; }
init();
/* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f;
};
$pkg.$init = $init;
return $pkg;
})();
$packages["main"] = (function() {
var $pkg = {}, $init, MagikCraft, main, lightning;
MagikCraft = $pkg.MagikCraft = $newType(0, $kindStruct, "main.MagikCraft", true, "main", true, function(x_) {
this.$val = this;
if (arguments.length === 0) {
this.x = 0;
return;
}
this.x = x_;
});
MagikCraft.ptr.prototype.shakti = function() {
var $ptr, m;
m = this;
return "You cast lightning";
};
MagikCraft.prototype.shakti = function() { return this.$val.shakti(); };
main = function(arg) {
var $ptr, arg;
lightning(arg);
};
lightning = function(num) {
var $ptr, i, magik, num, spell;
magik = new MagikCraft.ptr(0);
i = 0;
while (true) {
if (!(i < num)) { break; }
spell = $clone(magik, MagikCraft).shakti();
console.log(spell);
i = i + (1) >> 0;
}
};
MagikCraft.methods = [{prop: "shakti", name: "shakti", pkg: "main", typ: $funcType([], [$String], false)}];
MagikCraft.init("main", [{prop: "x", name: "x", exported: false, typ: $Int, tag: ""}]);
$init = function() {
$pkg.$init = function() {};
/* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
if ($pkg === $mainPkg) {
main();
$mainFinished = true;
}
/* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f;
};
$pkg.$init = $init;
return $pkg;
})();
$synthesizeMethods();
var $mainPkg = $packages["main"];
$packages["runtime"].$init();
$go($mainPkg.$init, []);
$flushConsole();
}).call(this);
//# sourceMappingURL=mc.js.map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment