github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/prelude/prelude.go (about) 1 package prelude 2 3 //go:generate go run genmin.go 4 5 // Prelude is the GopherJS JavaScript interop layer. 6 const Prelude = prelude + numeric + types + goroutines + jsmapping 7 8 const prelude = `Error.stackTraceLimit = Infinity; 9 10 var $global, $module; 11 if (typeof window !== "undefined") { /* web page */ 12 $global = window; 13 } else if (typeof self !== "undefined") { /* web worker */ 14 $global = self; 15 } else if (typeof global !== "undefined") { /* Node.js */ 16 $global = global; 17 $global.require = require; 18 } else { /* others (e.g. Nashorn) */ 19 $global = this; 20 } 21 22 if ($global === undefined || $global.Array === undefined) { 23 throw new Error("no global object found"); 24 } 25 if (typeof module !== "undefined") { 26 $module = module; 27 } 28 29 var $packages = {}, $idCounter = 0; 30 var $keys = function(m) { return m ? Object.keys(m) : []; }; 31 var $flushConsole = function() {}; 32 var $throwRuntimeError; /* set by package "runtime" */ 33 var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; 34 var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); }; 35 var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; }; 36 var $unused = function(v) {}; 37 38 var $mapArray = function(array, f) { 39 var newArray = new array.constructor(array.length); 40 for (var i = 0; i < array.length; i++) { 41 newArray[i] = f(array[i]); 42 } 43 return newArray; 44 }; 45 46 var $methodVal = function(recv, name) { 47 var vals = recv.$methodVals || {}; 48 recv.$methodVals = vals; /* noop for primitives */ 49 var f = vals[name]; 50 if (f !== undefined) { 51 return f; 52 } 53 var method = recv[name]; 54 f = function() { 55 $stackDepthOffset--; 56 try { 57 return method.apply(recv, arguments); 58 } finally { 59 $stackDepthOffset++; 60 } 61 }; 62 vals[name] = f; 63 return f; 64 }; 65 66 var $methodExpr = function(typ, name) { 67 var method = typ.prototype[name]; 68 if (method.$expr === undefined) { 69 method.$expr = function() { 70 $stackDepthOffset--; 71 try { 72 if (typ.wrapped) { 73 arguments[0] = new typ(arguments[0]); 74 } 75 return Function.call.apply(method, arguments); 76 } finally { 77 $stackDepthOffset++; 78 } 79 }; 80 } 81 return method.$expr; 82 }; 83 84 var $ifaceMethodExprs = {}; 85 var $ifaceMethodExpr = function(name) { 86 var expr = $ifaceMethodExprs["$" + name]; 87 if (expr === undefined) { 88 expr = $ifaceMethodExprs["$" + name] = function() { 89 $stackDepthOffset--; 90 try { 91 return Function.call.apply(arguments[0][name], arguments); 92 } finally { 93 $stackDepthOffset++; 94 } 95 }; 96 } 97 return expr; 98 }; 99 100 var $subslice = function(slice, low, high, max) { 101 if (high === undefined) { 102 high = slice.$length; 103 } 104 if (max === undefined) { 105 max = slice.$capacity; 106 } 107 if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) { 108 $throwRuntimeError("slice bounds out of range"); 109 } 110 if (slice === slice.constructor.nil) { 111 return slice; 112 } 113 var s = new slice.constructor(slice.$array); 114 s.$offset = slice.$offset + low; 115 s.$length = high - low; 116 s.$capacity = max - low; 117 return s; 118 }; 119 120 var $substring = function(str, low, high) { 121 if (low < 0 || high < low || high > str.length) { 122 $throwRuntimeError("slice bounds out of range"); 123 } 124 return str.substring(low, high); 125 }; 126 127 var $sliceToArray = function(slice) { 128 if (slice.$array.constructor !== Array) { 129 return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length); 130 } 131 return slice.$array.slice(slice.$offset, slice.$offset + slice.$length); 132 }; 133 134 var $decodeRune = function(str, pos) { 135 var c0 = str.charCodeAt(pos); 136 137 if (c0 < 0x80) { 138 return [c0, 1]; 139 } 140 141 if (c0 !== c0 || c0 < 0xC0) { 142 return [0xFFFD, 1]; 143 } 144 145 var c1 = str.charCodeAt(pos + 1); 146 if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) { 147 return [0xFFFD, 1]; 148 } 149 150 if (c0 < 0xE0) { 151 var r = (c0 & 0x1F) << 6 | (c1 & 0x3F); 152 if (r <= 0x7F) { 153 return [0xFFFD, 1]; 154 } 155 return [r, 2]; 156 } 157 158 var c2 = str.charCodeAt(pos + 2); 159 if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) { 160 return [0xFFFD, 1]; 161 } 162 163 if (c0 < 0xF0) { 164 var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F); 165 if (r <= 0x7FF) { 166 return [0xFFFD, 1]; 167 } 168 if (0xD800 <= r && r <= 0xDFFF) { 169 return [0xFFFD, 1]; 170 } 171 return [r, 3]; 172 } 173 174 var c3 = str.charCodeAt(pos + 3); 175 if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) { 176 return [0xFFFD, 1]; 177 } 178 179 if (c0 < 0xF8) { 180 var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F); 181 if (r <= 0xFFFF || 0x10FFFF < r) { 182 return [0xFFFD, 1]; 183 } 184 return [r, 4]; 185 } 186 187 return [0xFFFD, 1]; 188 }; 189 190 var $encodeRune = function(r) { 191 if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) { 192 r = 0xFFFD; 193 } 194 if (r <= 0x7F) { 195 return String.fromCharCode(r); 196 } 197 if (r <= 0x7FF) { 198 return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F)); 199 } 200 if (r <= 0xFFFF) { 201 return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); 202 } 203 return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); 204 }; 205 206 var $stringToBytes = function(str) { 207 var array = new Uint8Array(str.length); 208 for (var i = 0; i < str.length; i++) { 209 array[i] = str.charCodeAt(i); 210 } 211 return array; 212 }; 213 214 var $bytesToString = function(slice) { 215 if (slice.$length === 0) { 216 return ""; 217 } 218 var str = ""; 219 for (var i = 0; i < slice.$length; i += 10000) { 220 str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000))); 221 } 222 return str; 223 }; 224 225 var $stringToRunes = function(str) { 226 var array = new Int32Array(str.length); 227 var rune, j = 0; 228 for (var i = 0; i < str.length; i += rune[1], j++) { 229 rune = $decodeRune(str, i); 230 array[j] = rune[0]; 231 } 232 return array.subarray(0, j); 233 }; 234 235 var $runesToString = function(slice) { 236 if (slice.$length === 0) { 237 return ""; 238 } 239 var str = ""; 240 for (var i = 0; i < slice.$length; i++) { 241 str += $encodeRune(slice.$array[slice.$offset + i]); 242 } 243 return str; 244 }; 245 246 var $copyString = function(dst, src) { 247 var n = Math.min(src.length, dst.$length); 248 for (var i = 0; i < n; i++) { 249 dst.$array[dst.$offset + i] = src.charCodeAt(i); 250 } 251 return n; 252 }; 253 254 var $copySlice = function(dst, src) { 255 var n = Math.min(src.$length, dst.$length); 256 $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem); 257 return n; 258 }; 259 260 var $copyArray = function(dst, src, dstOffset, srcOffset, n, elem) { 261 if (n === 0 || (dst === src && dstOffset === srcOffset)) { 262 return; 263 } 264 265 if (src.subarray) { 266 dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset); 267 return; 268 } 269 270 switch (elem.kind) { 271 case $kindArray: 272 case $kindStruct: 273 if (dst === src && dstOffset > srcOffset) { 274 for (var i = n - 1; i >= 0; i--) { 275 elem.copy(dst[dstOffset + i], src[srcOffset + i]); 276 } 277 return; 278 } 279 for (var i = 0; i < n; i++) { 280 elem.copy(dst[dstOffset + i], src[srcOffset + i]); 281 } 282 return; 283 } 284 285 if (dst === src && dstOffset > srcOffset) { 286 for (var i = n - 1; i >= 0; i--) { 287 dst[dstOffset + i] = src[srcOffset + i]; 288 } 289 return; 290 } 291 for (var i = 0; i < n; i++) { 292 dst[dstOffset + i] = src[srcOffset + i]; 293 } 294 }; 295 296 var $clone = function(src, type) { 297 var clone = type.zero(); 298 type.copy(clone, src); 299 return clone; 300 }; 301 302 var $pointerOfStructConversion = function(obj, type) { 303 if(obj.$proxies === undefined) { 304 obj.$proxies = {}; 305 obj.$proxies[obj.constructor.string] = obj; 306 } 307 var proxy = obj.$proxies[type.string]; 308 if (proxy === undefined) { 309 var properties = {}; 310 for (var i = 0; i < type.elem.fields.length; i++) { 311 (function(fieldProp) { 312 properties[fieldProp] = { 313 get: function() { return obj[fieldProp]; }, 314 set: function(value) { obj[fieldProp] = value; } 315 }; 316 })(type.elem.fields[i].prop); 317 } 318 proxy = Object.create(type.prototype, properties); 319 proxy.$val = proxy; 320 obj.$proxies[type.string] = proxy; 321 proxy.$proxies = obj.$proxies; 322 } 323 return proxy; 324 }; 325 326 var $append = function(slice) { 327 return $internalAppend(slice, arguments, 1, arguments.length - 1); 328 }; 329 330 var $appendSlice = function(slice, toAppend) { 331 if (toAppend.constructor === String) { 332 var bytes = $stringToBytes(toAppend); 333 return $internalAppend(slice, bytes, 0, bytes.length); 334 } 335 return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length); 336 }; 337 338 var $internalAppend = function(slice, array, offset, length) { 339 if (length === 0) { 340 return slice; 341 } 342 343 var newArray = slice.$array; 344 var newOffset = slice.$offset; 345 var newLength = slice.$length + length; 346 var newCapacity = slice.$capacity; 347 348 if (newLength > newCapacity) { 349 newOffset = 0; 350 newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4)); 351 352 if (slice.$array.constructor === Array) { 353 newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length); 354 newArray.length = newCapacity; 355 var zero = slice.constructor.elem.zero; 356 for (var i = slice.$length; i < newCapacity; i++) { 357 newArray[i] = zero(); 358 } 359 } else { 360 newArray = new slice.$array.constructor(newCapacity); 361 newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length)); 362 } 363 } 364 365 $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem); 366 367 var newSlice = new slice.constructor(newArray); 368 newSlice.$offset = newOffset; 369 newSlice.$length = newLength; 370 newSlice.$capacity = newCapacity; 371 return newSlice; 372 }; 373 374 var $equal = function(a, b, type) { 375 if (type === $jsObjectPtr) { 376 return a === b; 377 } 378 switch (type.kind) { 379 case $kindComplex64: 380 case $kindComplex128: 381 return a.$real === b.$real && a.$imag === b.$imag; 382 case $kindInt64: 383 case $kindUint64: 384 return a.$high === b.$high && a.$low === b.$low; 385 case $kindArray: 386 if (a.length !== b.length) { 387 return false; 388 } 389 for (var i = 0; i < a.length; i++) { 390 if (!$equal(a[i], b[i], type.elem)) { 391 return false; 392 } 393 } 394 return true; 395 case $kindStruct: 396 for (var i = 0; i < type.fields.length; i++) { 397 var f = type.fields[i]; 398 if (!$equal(a[f.prop], b[f.prop], f.typ)) { 399 return false; 400 } 401 } 402 return true; 403 case $kindInterface: 404 return $interfaceIsEqual(a, b); 405 default: 406 return a === b; 407 } 408 }; 409 410 var $interfaceIsEqual = function(a, b) { 411 if (a === $ifaceNil || b === $ifaceNil) { 412 return a === b; 413 } 414 if (a.constructor !== b.constructor) { 415 return false; 416 } 417 if (a.constructor === $jsObjectPtr) { 418 return a.object === b.object; 419 } 420 if (!a.constructor.comparable) { 421 $throwRuntimeError("comparing uncomparable type " + a.constructor.string); 422 } 423 return $equal(a.$val, b.$val, a.constructor); 424 }; 425 `