github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/prelude/prelude.js (about) 1 Error.stackTraceLimit = Infinity; 2 3 var $NaN = NaN; 4 var $global, $module; 5 if (typeof window !== "undefined") { /* web page */ 6 $global = window; 7 } else if (typeof self !== "undefined") { /* web worker */ 8 $global = self; 9 } else if (typeof global !== "undefined") { /* Node.js */ 10 $global = global; 11 $global.require = require; 12 } else { /* others (e.g. Nashorn) */ 13 $global = this; 14 } 15 16 if ($global === undefined || $global.Array === undefined) { 17 throw new Error("no global object found"); 18 } 19 if (typeof module !== "undefined") { 20 $module = module; 21 } 22 23 if (!$global.fs && $global.require) { 24 try { 25 var fs = $global.require('fs'); 26 if (typeof fs === "object" && fs !== null && Object.keys(fs).length !== 0) { 27 $global.fs = fs; 28 } 29 } catch (e) { /* Ignore if the module couldn't be loaded. */ } 30 } 31 32 if (!$global.fs) { 33 var outputBuf = ""; 34 var decoder = new TextDecoder("utf-8"); 35 $global.fs = { 36 constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused 37 writeSync: function writeSync(fd, buf) { 38 outputBuf += decoder.decode(buf); 39 var nl = outputBuf.lastIndexOf("\n"); 40 if (nl != -1) { 41 console.log(outputBuf.substr(0, nl)); 42 outputBuf = outputBuf.substr(nl + 1); 43 } 44 return buf.length; 45 }, 46 write: function write(fd, buf, offset, length, position, callback) { 47 if (offset !== 0 || length !== buf.length || position !== null) { 48 callback(enosys()); 49 return; 50 } 51 var n = this.writeSync(fd, buf); 52 callback(null, n); 53 } 54 }; 55 } 56 57 var $linknames = {} // Collection of functions referenced by a go:linkname directive. 58 var $packages = {}, $idCounter = 0; 59 var $keys = m => { return m ? Object.keys(m) : []; }; 60 var $flushConsole = () => { }; 61 var $throwRuntimeError; /* set by package "runtime" */ 62 var $throwNilPointerError = () => { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; 63 var $call = (fn, rcvr, args) => { return fn.apply(rcvr, args); }; 64 var $makeFunc = fn => { return function(...args) { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(args, []))), $emptyInterface); }; }; 65 var $unused = v => { }; 66 var $print = console.log; 67 // Under Node we can emulate print() more closely by avoiding a newline. 68 if (($global.process !== undefined) && $global.require) { 69 try { 70 var util = $global.require('util'); 71 $print = function(...args) { $global.process.stderr.write(util.format.apply(this, args)); }; 72 } catch (e) { 73 // Failed to require util module, keep using console.log(). 74 } 75 } 76 var $println = console.log 77 78 var $initAllLinknames = () => { 79 var names = $keys($packages); 80 for (var i = 0; i < names.length; i++) { 81 var f = $packages[names[i]]["$initLinknames"]; 82 if (typeof f == 'function') { 83 f(); 84 } 85 } 86 } 87 88 var $mapArray = (array, f) => { 89 var newArray = new array.constructor(array.length); 90 for (var i = 0; i < array.length; i++) { 91 newArray[i] = f(array[i]); 92 } 93 return newArray; 94 }; 95 96 // $mapIndex returns the value of the given key in m, or undefined if m is nil/undefined or not a map 97 var $mapIndex = (m, key) => { 98 return typeof m.get === "function" ? m.get(key) : undefined; 99 }; 100 // $mapDelete deletes the key and associated value from m. If m is nil/undefined or not a map, $mapDelete is a no-op 101 var $mapDelete = (m, key) => { 102 typeof m.delete === "function" && m.delete(key) 103 }; 104 // Returns a method bound to the receiver instance, safe to invoke as a 105 // standalone function. Bound function is cached for later reuse. 106 var $methodVal = (recv, name) => { 107 var vals = recv.$methodVals || {}; 108 recv.$methodVals = vals; /* noop for primitives */ 109 var f = vals[name]; 110 if (f !== undefined) { 111 return f; 112 } 113 var method = recv[name]; 114 f = method.bind(recv); 115 vals[name] = f; 116 return f; 117 }; 118 119 var $methodExpr = (typ, name) => { 120 var method = typ.prototype[name]; 121 if (method.$expr === undefined) { 122 method.$expr = (...args) => { 123 $stackDepthOffset--; 124 try { 125 if (typ.wrapped) { 126 args[0] = new typ(args[0]); 127 } 128 return Function.call.apply(method, args); 129 } finally { 130 $stackDepthOffset++; 131 } 132 }; 133 } 134 return method.$expr; 135 }; 136 137 var $ifaceMethodExprs = {}; 138 var $ifaceMethodExpr = name => { 139 var expr = $ifaceMethodExprs["$" + name]; 140 if (expr === undefined) { 141 expr = $ifaceMethodExprs["$" + name] = (...args) => { 142 $stackDepthOffset--; 143 try { 144 return Function.call.apply(args[0][name], args); 145 } finally { 146 $stackDepthOffset++; 147 } 148 }; 149 } 150 return expr; 151 }; 152 153 var $subslice = (slice, low, high, max) => { 154 if (high === undefined) { 155 high = slice.$length; 156 } 157 if (max === undefined) { 158 max = slice.$capacity; 159 } 160 if (low < 0 || high < low || max < high || high > slice.$capacity || max > slice.$capacity) { 161 $throwRuntimeError("slice bounds out of range"); 162 } 163 if (slice === slice.constructor.nil) { 164 return slice; 165 } 166 var s = new slice.constructor(slice.$array); 167 s.$offset = slice.$offset + low; 168 s.$length = high - low; 169 s.$capacity = max - low; 170 return s; 171 }; 172 173 var $substring = (str, low, high) => { 174 if (low < 0 || high < low || high > str.length) { 175 $throwRuntimeError("slice bounds out of range"); 176 } 177 return str.substring(low, high); 178 }; 179 180 // Convert Go slice to an equivalent JS array type. 181 var $sliceToNativeArray = slice => { 182 if (slice.$array.constructor !== Array) { 183 return slice.$array.subarray(slice.$offset, slice.$offset + slice.$length); 184 } 185 return slice.$array.slice(slice.$offset, slice.$offset + slice.$length); 186 }; 187 188 // Convert Go slice to a pointer to an underlying Go array. 189 // 190 // Note that an array pointer can be represented by an "unwrapped" native array 191 // type, and it will be wrapped back into its Go type when necessary. 192 var $sliceToGoArray = (slice, arrayPtrType) => { 193 var arrayType = arrayPtrType.elem; 194 if (arrayType !== undefined && slice.$length < arrayType.len) { 195 $throwRuntimeError("cannot convert slice with length " + slice.$length + " to pointer to array with length " + arrayType.len); 196 } 197 if (slice == slice.constructor.nil) { 198 return arrayPtrType.nil; // Nil slice converts to nil array pointer. 199 } 200 if (slice.$array.constructor !== Array) { 201 return slice.$array.subarray(slice.$offset, slice.$offset + arrayType.len); 202 } 203 if (slice.$offset == 0 && slice.$length == slice.$capacity && slice.$length == arrayType.len) { 204 return slice.$array; 205 } 206 if (arrayType.len == 0) { 207 return new arrayType([]); 208 } 209 210 // Array.slice (unlike TypedArray.subarray) returns a copy of an array range, 211 // which is not sharing memory with the original one, which violates the spec 212 // for slice to array conversion. This is incompatible with the Go spec, in 213 // particular that the assignments to the array elements would be visible in 214 // the slice. Prefer to fail explicitly instead of creating subtle bugs. 215 $throwRuntimeError("gopherjs: non-numeric slice to underlying array conversion is not supported for subslices"); 216 }; 217 218 // Convert between compatible slice types (e.g. native and names). 219 var $convertSliceType = (slice, desiredType) => { 220 if (slice == slice.constructor.nil) { 221 return desiredType.nil; // Preserve nil value. 222 } 223 224 return $subslice(new desiredType(slice.$array), slice.$offset, slice.$offset + slice.$length); 225 } 226 227 var $decodeRune = (str, pos) => { 228 var c0 = str.charCodeAt(pos); 229 230 if (c0 < 0x80) { 231 return [c0, 1]; 232 } 233 234 if (c0 !== c0 || c0 < 0xC0) { 235 return [0xFFFD, 1]; 236 } 237 238 var c1 = str.charCodeAt(pos + 1); 239 if (c1 !== c1 || c1 < 0x80 || 0xC0 <= c1) { 240 return [0xFFFD, 1]; 241 } 242 243 if (c0 < 0xE0) { 244 var r = (c0 & 0x1F) << 6 | (c1 & 0x3F); 245 if (r <= 0x7F) { 246 return [0xFFFD, 1]; 247 } 248 return [r, 2]; 249 } 250 251 var c2 = str.charCodeAt(pos + 2); 252 if (c2 !== c2 || c2 < 0x80 || 0xC0 <= c2) { 253 return [0xFFFD, 1]; 254 } 255 256 if (c0 < 0xF0) { 257 var r = (c0 & 0x0F) << 12 | (c1 & 0x3F) << 6 | (c2 & 0x3F); 258 if (r <= 0x7FF) { 259 return [0xFFFD, 1]; 260 } 261 if (0xD800 <= r && r <= 0xDFFF) { 262 return [0xFFFD, 1]; 263 } 264 return [r, 3]; 265 } 266 267 var c3 = str.charCodeAt(pos + 3); 268 if (c3 !== c3 || c3 < 0x80 || 0xC0 <= c3) { 269 return [0xFFFD, 1]; 270 } 271 272 if (c0 < 0xF8) { 273 var r = (c0 & 0x07) << 18 | (c1 & 0x3F) << 12 | (c2 & 0x3F) << 6 | (c3 & 0x3F); 274 if (r <= 0xFFFF || 0x10FFFF < r) { 275 return [0xFFFD, 1]; 276 } 277 return [r, 4]; 278 } 279 280 return [0xFFFD, 1]; 281 }; 282 283 var $encodeRune = r => { 284 if (r < 0 || r > 0x10FFFF || (0xD800 <= r && r <= 0xDFFF)) { 285 r = 0xFFFD; 286 } 287 if (r <= 0x7F) { 288 return String.fromCharCode(r); 289 } 290 if (r <= 0x7FF) { 291 return String.fromCharCode(0xC0 | r >> 6, 0x80 | (r & 0x3F)); 292 } 293 if (r <= 0xFFFF) { 294 return String.fromCharCode(0xE0 | r >> 12, 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); 295 } 296 return String.fromCharCode(0xF0 | r >> 18, 0x80 | (r >> 12 & 0x3F), 0x80 | (r >> 6 & 0x3F), 0x80 | (r & 0x3F)); 297 }; 298 299 var $stringToBytes = str => { 300 var array = new Uint8Array(str.length); 301 for (var i = 0; i < str.length; i++) { 302 array[i] = str.charCodeAt(i); 303 } 304 return array; 305 }; 306 307 var $bytesToString = slice => { 308 if (slice.$length === 0) { 309 return ""; 310 } 311 var str = ""; 312 for (var i = 0; i < slice.$length; i += 10000) { 313 str += String.fromCharCode.apply(undefined, slice.$array.subarray(slice.$offset + i, slice.$offset + Math.min(slice.$length, i + 10000))); 314 } 315 return str; 316 }; 317 318 var $stringToRunes = str => { 319 var array = new Int32Array(str.length); 320 var rune, j = 0; 321 for (var i = 0; i < str.length; i += rune[1], j++) { 322 rune = $decodeRune(str, i); 323 array[j] = rune[0]; 324 } 325 return array.subarray(0, j); 326 }; 327 328 var $runesToString = slice => { 329 if (slice.$length === 0) { 330 return ""; 331 } 332 var str = ""; 333 for (var i = 0; i < slice.$length; i++) { 334 str += $encodeRune(slice.$array[slice.$offset + i]); 335 } 336 return str; 337 }; 338 339 var $copyString = (dst, src) => { 340 var n = Math.min(src.length, dst.$length); 341 for (var i = 0; i < n; i++) { 342 dst.$array[dst.$offset + i] = src.charCodeAt(i); 343 } 344 return n; 345 }; 346 347 var $copySlice = (dst, src) => { 348 var n = Math.min(src.$length, dst.$length); 349 $copyArray(dst.$array, src.$array, dst.$offset, src.$offset, n, dst.constructor.elem); 350 return n; 351 }; 352 353 var $copyArray = (dst, src, dstOffset, srcOffset, n, elem) => { 354 if (n === 0 || (dst === src && dstOffset === srcOffset)) { 355 return; 356 } 357 358 if (src.subarray) { 359 dst.set(src.subarray(srcOffset, srcOffset + n), dstOffset); 360 return; 361 } 362 363 switch (elem.kind) { 364 case $kindArray: 365 case $kindStruct: 366 if (dst === src && dstOffset > srcOffset) { 367 for (var i = n - 1; i >= 0; i--) { 368 elem.copy(dst[dstOffset + i], src[srcOffset + i]); 369 } 370 return; 371 } 372 for (var i = 0; i < n; i++) { 373 elem.copy(dst[dstOffset + i], src[srcOffset + i]); 374 } 375 return; 376 } 377 378 if (dst === src && dstOffset > srcOffset) { 379 for (var i = n - 1; i >= 0; i--) { 380 dst[dstOffset + i] = src[srcOffset + i]; 381 } 382 return; 383 } 384 for (var i = 0; i < n; i++) { 385 dst[dstOffset + i] = src[srcOffset + i]; 386 } 387 }; 388 389 var $clone = (src, type) => { 390 var clone = type.zero(); 391 type.copy(clone, src); 392 return clone; 393 }; 394 395 var $pointerOfStructConversion = (obj, type) => { 396 if (obj.$proxies === undefined) { 397 obj.$proxies = {}; 398 obj.$proxies[obj.constructor.string] = obj; 399 } 400 var proxy = obj.$proxies[type.string]; 401 if (proxy === undefined) { 402 var properties = {}; 403 for (var i = 0; i < type.elem.fields.length; i++) { 404 (fieldProp => { 405 properties[fieldProp] = { 406 get() { return obj[fieldProp]; }, 407 set(value) { obj[fieldProp] = value; } 408 }; 409 })(type.elem.fields[i].prop); 410 } 411 proxy = Object.create(type.prototype, properties); 412 proxy.$val = proxy; 413 obj.$proxies[type.string] = proxy; 414 proxy.$proxies = obj.$proxies; 415 } 416 return proxy; 417 }; 418 419 var $append = function (slice) { 420 return $internalAppend(slice, arguments, 1, arguments.length - 1); 421 }; 422 423 var $appendSlice = (slice, toAppend) => { 424 if (toAppend.constructor === String) { 425 var bytes = $stringToBytes(toAppend); 426 return $internalAppend(slice, bytes, 0, bytes.length); 427 } 428 return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length); 429 }; 430 431 var $internalAppend = (slice, array, offset, length) => { 432 if (length === 0) { 433 return slice; 434 } 435 436 var newArray = slice.$array; 437 var newOffset = slice.$offset; 438 var newLength = slice.$length + length; 439 var newCapacity = slice.$capacity; 440 441 if (newLength > newCapacity) { 442 newOffset = 0; 443 newCapacity = Math.max(newLength, slice.$capacity < 1024 ? slice.$capacity * 2 : Math.floor(slice.$capacity * 5 / 4)); 444 445 if (slice.$array.constructor === Array) { 446 newArray = slice.$array.slice(slice.$offset, slice.$offset + slice.$length); 447 newArray.length = newCapacity; 448 var zero = slice.constructor.elem.zero; 449 for (var i = slice.$length; i < newCapacity; i++) { 450 newArray[i] = zero(); 451 } 452 } else { 453 newArray = new slice.$array.constructor(newCapacity); 454 newArray.set(slice.$array.subarray(slice.$offset, slice.$offset + slice.$length)); 455 } 456 } 457 458 $copyArray(newArray, array, newOffset + slice.$length, offset, length, slice.constructor.elem); 459 460 var newSlice = new slice.constructor(newArray); 461 newSlice.$offset = newOffset; 462 newSlice.$length = newLength; 463 newSlice.$capacity = newCapacity; 464 return newSlice; 465 }; 466 467 var $equal = (a, b, type) => { 468 if (type === $jsObjectPtr) { 469 return a === b; 470 } 471 switch (type.kind) { 472 case $kindComplex64: 473 case $kindComplex128: 474 return a.$real === b.$real && a.$imag === b.$imag; 475 case $kindInt64: 476 case $kindUint64: 477 return a.$high === b.$high && a.$low === b.$low; 478 case $kindArray: 479 if (a.length !== b.length) { 480 return false; 481 } 482 for (var i = 0; i < a.length; i++) { 483 if (!$equal(a[i], b[i], type.elem)) { 484 return false; 485 } 486 } 487 return true; 488 case $kindStruct: 489 for (var i = 0; i < type.fields.length; i++) { 490 var f = type.fields[i]; 491 if (!$equal(a[f.prop], b[f.prop], f.typ)) { 492 return false; 493 } 494 } 495 return true; 496 case $kindInterface: 497 return $interfaceIsEqual(a, b); 498 default: 499 return a === b; 500 } 501 }; 502 503 var $interfaceIsEqual = (a, b) => { 504 if (a === $ifaceNil || b === $ifaceNil) { 505 return a === b; 506 } 507 if (a.constructor !== b.constructor) { 508 return false; 509 } 510 if (a.constructor === $jsObjectPtr) { 511 return a.object === b.object; 512 } 513 if (!a.constructor.comparable) { 514 $throwRuntimeError("comparing uncomparable type " + a.constructor.string); 515 } 516 return $equal(a.$val, b.$val, a.constructor); 517 }; 518 519 var $unsafeMethodToFunction = (typ, name, isPtr) => { 520 if (isPtr) { 521 return (r, ...args) => { 522 var ptrType = $ptrType(typ); 523 if (r.constructor != ptrType) { 524 switch (typ.kind) { 525 case $kindStruct: 526 r = $pointerOfStructConversion(r, ptrType); 527 break; 528 case $kindArray: 529 r = new ptrType(r); 530 break; 531 default: 532 r = new ptrType(r.$get, r.$set, r.$target); 533 } 534 } 535 return r[name](...args); 536 }; 537 } else { 538 return (r, ...args) => { 539 var ptrType = $ptrType(typ); 540 if (r.constructor != ptrType) { 541 switch (typ.kind) { 542 case $kindStruct: 543 r = $clone(r, typ); 544 break; 545 case $kindSlice: 546 r = $convertSliceType(r, typ); 547 break; 548 case $kindComplex64: 549 case $kindComplex128: 550 r = new typ(r.$real, r.$imag); 551 break; 552 default: 553 r = new typ(r); 554 } 555 } 556 return r[name](...args); 557 }; 558 } 559 }; 560 561 var $id = x => { 562 return x; 563 }; 564 565 var $instanceOf = (x, y) => { 566 return x instanceof y; 567 }; 568 569 var $typeOf = x => { 570 return typeof (x); 571 };