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  `