github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/prelude/types.go (about) 1 package prelude 2 3 const types = ` 4 var $kindBool = 1; 5 var $kindInt = 2; 6 var $kindInt8 = 3; 7 var $kindInt16 = 4; 8 var $kindInt32 = 5; 9 var $kindInt64 = 6; 10 var $kindUint = 7; 11 var $kindUint8 = 8; 12 var $kindUint16 = 9; 13 var $kindUint32 = 10; 14 var $kindUint64 = 11; 15 var $kindUintptr = 12; 16 var $kindFloat32 = 13; 17 var $kindFloat64 = 14; 18 var $kindComplex64 = 15; 19 var $kindComplex128 = 16; 20 var $kindArray = 17; 21 var $kindChan = 18; 22 var $kindFunc = 19; 23 var $kindInterface = 20; 24 var $kindMap = 21; 25 var $kindPtr = 22; 26 var $kindSlice = 23; 27 var $kindString = 24; 28 var $kindStruct = 25; 29 var $kindUnsafePointer = 26; 30 31 var $methodSynthesizers = []; 32 var $addMethodSynthesizer = function(f) { 33 if ($methodSynthesizers === null) { 34 f(); 35 return; 36 } 37 $methodSynthesizers.push(f); 38 }; 39 var $synthesizeMethods = function() { 40 $methodSynthesizers.forEach(function(f) { f(); }); 41 $methodSynthesizers = null; 42 }; 43 44 var $ifaceKeyFor = function(x) { 45 if (x === $ifaceNil) { 46 return 'nil'; 47 } 48 var c = x.constructor; 49 return c.string + '$' + c.keyFor(x.$val); 50 }; 51 52 var $identity = function(x) { return x; }; 53 54 var $typeIDCounter = 0; 55 56 var $idKey = function(x) { 57 if (x.$id === undefined) { 58 $idCounter++; 59 x.$id = $idCounter; 60 } 61 return String(x.$id); 62 }; 63 64 var $newType = function(size, kind, string, named, pkg, exported, constructor) { 65 var typ; 66 switch(kind) { 67 case $kindBool: 68 case $kindInt: 69 case $kindInt8: 70 case $kindInt16: 71 case $kindInt32: 72 case $kindUint: 73 case $kindUint8: 74 case $kindUint16: 75 case $kindUint32: 76 case $kindUintptr: 77 case $kindUnsafePointer: 78 typ = function(v) { this.$val = v; }; 79 typ.wrapped = true; 80 typ.keyFor = $identity; 81 break; 82 83 case $kindString: 84 typ = function(v) { this.$val = v; }; 85 typ.wrapped = true; 86 typ.keyFor = function(x) { return "$" + x; }; 87 break; 88 89 case $kindFloat32: 90 case $kindFloat64: 91 typ = function(v) { this.$val = v; }; 92 typ.wrapped = true; 93 typ.keyFor = function(x) { return $floatKey(x); }; 94 break; 95 96 case $kindInt64: 97 typ = function(high, low) { 98 this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >> 0; 99 this.$low = low >>> 0; 100 this.$val = this; 101 }; 102 typ.keyFor = function(x) { return x.$high + "$" + x.$low; }; 103 break; 104 105 case $kindUint64: 106 typ = function(high, low) { 107 this.$high = (high + Math.floor(Math.ceil(low) / 4294967296)) >>> 0; 108 this.$low = low >>> 0; 109 this.$val = this; 110 }; 111 typ.keyFor = function(x) { return x.$high + "$" + x.$low; }; 112 break; 113 114 case $kindComplex64: 115 typ = function(real, imag) { 116 this.$real = $fround(real); 117 this.$imag = $fround(imag); 118 this.$val = this; 119 }; 120 typ.keyFor = function(x) { return x.$real + "$" + x.$imag; }; 121 break; 122 123 case $kindComplex128: 124 typ = function(real, imag) { 125 this.$real = real; 126 this.$imag = imag; 127 this.$val = this; 128 }; 129 typ.keyFor = function(x) { return x.$real + "$" + x.$imag; }; 130 break; 131 132 case $kindArray: 133 typ = function(v) { this.$val = v; }; 134 typ.wrapped = true; 135 typ.ptr = $newType(4, $kindPtr, "*" + string, false, "", false, function(array) { 136 this.$get = function() { return array; }; 137 this.$set = function(v) { typ.copy(this, v); }; 138 this.$val = array; 139 }); 140 typ.init = function(elem, len) { 141 typ.elem = elem; 142 typ.len = len; 143 typ.comparable = elem.comparable; 144 typ.keyFor = function(x) { 145 return Array.prototype.join.call($mapArray(x, function(e) { 146 return String(elem.keyFor(e)).replace(/\\/g, "\\\\").replace(/\$/g, "\\$"); 147 }), "$"); 148 }; 149 typ.copy = function(dst, src) { 150 $copyArray(dst, src, 0, 0, src.length, elem); 151 }; 152 typ.ptr.init(typ); 153 Object.defineProperty(typ.ptr.nil, "nilCheck", { get: $throwNilPointerError }); 154 }; 155 break; 156 157 case $kindChan: 158 typ = function(v) { this.$val = v; }; 159 typ.wrapped = true; 160 typ.keyFor = $idKey; 161 typ.init = function(elem, sendOnly, recvOnly) { 162 typ.elem = elem; 163 typ.sendOnly = sendOnly; 164 typ.recvOnly = recvOnly; 165 }; 166 break; 167 168 case $kindFunc: 169 typ = function(v) { this.$val = v; }; 170 typ.wrapped = true; 171 typ.init = function(params, results, variadic) { 172 typ.params = params; 173 typ.results = results; 174 typ.variadic = variadic; 175 typ.comparable = false; 176 }; 177 break; 178 179 case $kindInterface: 180 typ = { implementedBy: {}, missingMethodFor: {} }; 181 typ.keyFor = $ifaceKeyFor; 182 typ.init = function(methods) { 183 typ.methods = methods; 184 methods.forEach(function(m) { 185 $ifaceNil[m.prop] = $throwNilPointerError; 186 }); 187 }; 188 break; 189 190 case $kindMap: 191 typ = function(v) { this.$val = v; }; 192 typ.wrapped = true; 193 typ.init = function(key, elem) { 194 typ.key = key; 195 typ.elem = elem; 196 typ.comparable = false; 197 }; 198 break; 199 200 case $kindPtr: 201 typ = constructor || function(getter, setter, target) { 202 this.$get = getter; 203 this.$set = setter; 204 this.$target = target; 205 this.$val = this; 206 }; 207 typ.keyFor = $idKey; 208 typ.init = function(elem) { 209 typ.elem = elem; 210 typ.wrapped = (elem.kind === $kindArray); 211 typ.nil = new typ($throwNilPointerError, $throwNilPointerError); 212 }; 213 break; 214 215 case $kindSlice: 216 typ = function(array) { 217 if (array.constructor !== typ.nativeArray) { 218 array = new typ.nativeArray(array); 219 } 220 this.$array = array; 221 this.$offset = 0; 222 this.$length = array.length; 223 this.$capacity = array.length; 224 this.$val = this; 225 }; 226 typ.init = function(elem) { 227 typ.elem = elem; 228 typ.comparable = false; 229 typ.nativeArray = $nativeArray(elem.kind); 230 typ.nil = new typ([]); 231 }; 232 break; 233 234 case $kindStruct: 235 typ = function(v) { this.$val = v; }; 236 typ.wrapped = true; 237 typ.ptr = $newType(4, $kindPtr, "*" + string, false, pkg, exported, constructor); 238 typ.ptr.elem = typ; 239 typ.ptr.prototype.$get = function() { return this; }; 240 typ.ptr.prototype.$set = function(v) { typ.copy(this, v); }; 241 typ.init = function(pkgPath, fields) { 242 typ.pkgPath = pkgPath; 243 typ.fields = fields; 244 fields.forEach(function(f) { 245 if (!f.typ.comparable) { 246 typ.comparable = false; 247 } 248 }); 249 typ.keyFor = function(x) { 250 var val = x.$val; 251 return $mapArray(fields, function(f) { 252 return String(f.typ.keyFor(val[f.prop])).replace(/\\/g, "\\\\").replace(/\$/g, "\\$"); 253 }).join("$"); 254 }; 255 typ.copy = function(dst, src) { 256 for (var i = 0; i < fields.length; i++) { 257 var f = fields[i]; 258 switch (f.typ.kind) { 259 case $kindArray: 260 case $kindStruct: 261 f.typ.copy(dst[f.prop], src[f.prop]); 262 continue; 263 default: 264 dst[f.prop] = src[f.prop]; 265 continue; 266 } 267 } 268 }; 269 /* nil value */ 270 var properties = {}; 271 fields.forEach(function(f) { 272 properties[f.prop] = { get: $throwNilPointerError, set: $throwNilPointerError }; 273 }); 274 typ.ptr.nil = Object.create(constructor.prototype, properties); 275 typ.ptr.nil.$val = typ.ptr.nil; 276 /* methods for embedded fields */ 277 $addMethodSynthesizer(function() { 278 var synthesizeMethod = function(target, m, f) { 279 if (target.prototype[m.prop] !== undefined) { return; } 280 target.prototype[m.prop] = function() { 281 var v = this.$val[f.prop]; 282 if (f.typ === $jsObjectPtr) { 283 v = new $jsObjectPtr(v); 284 } 285 if (v.$val === undefined) { 286 v = new f.typ(v); 287 } 288 return v[m.prop].apply(v, arguments); 289 }; 290 }; 291 fields.forEach(function(f) { 292 if (f.embedded) { 293 $methodSet(f.typ).forEach(function(m) { 294 synthesizeMethod(typ, m, f); 295 synthesizeMethod(typ.ptr, m, f); 296 }); 297 $methodSet($ptrType(f.typ)).forEach(function(m) { 298 synthesizeMethod(typ.ptr, m, f); 299 }); 300 } 301 }); 302 }); 303 }; 304 break; 305 306 default: 307 $panic(new $String("invalid kind: " + kind)); 308 } 309 310 switch (kind) { 311 case $kindBool: 312 case $kindMap: 313 typ.zero = function() { return false; }; 314 break; 315 316 case $kindInt: 317 case $kindInt8: 318 case $kindInt16: 319 case $kindInt32: 320 case $kindUint: 321 case $kindUint8 : 322 case $kindUint16: 323 case $kindUint32: 324 case $kindUintptr: 325 case $kindUnsafePointer: 326 case $kindFloat32: 327 case $kindFloat64: 328 typ.zero = function() { return 0; }; 329 break; 330 331 case $kindString: 332 typ.zero = function() { return ""; }; 333 break; 334 335 case $kindInt64: 336 case $kindUint64: 337 case $kindComplex64: 338 case $kindComplex128: 339 var zero = new typ(0, 0); 340 typ.zero = function() { return zero; }; 341 break; 342 343 case $kindPtr: 344 case $kindSlice: 345 typ.zero = function() { return typ.nil; }; 346 break; 347 348 case $kindChan: 349 typ.zero = function() { return $chanNil; }; 350 break; 351 352 case $kindFunc: 353 typ.zero = function() { return $throwNilPointerError; }; 354 break; 355 356 case $kindInterface: 357 typ.zero = function() { return $ifaceNil; }; 358 break; 359 360 case $kindArray: 361 typ.zero = function() { 362 var arrayClass = $nativeArray(typ.elem.kind); 363 if (arrayClass !== Array) { 364 return new arrayClass(typ.len); 365 } 366 var array = new Array(typ.len); 367 for (var i = 0; i < typ.len; i++) { 368 array[i] = typ.elem.zero(); 369 } 370 return array; 371 }; 372 break; 373 374 case $kindStruct: 375 typ.zero = function() { return new typ.ptr(); }; 376 break; 377 378 default: 379 $panic(new $String("invalid kind: " + kind)); 380 } 381 382 typ.id = $typeIDCounter; 383 $typeIDCounter++; 384 typ.size = size; 385 typ.kind = kind; 386 typ.string = string; 387 typ.named = named; 388 typ.pkg = pkg; 389 typ.exported = exported; 390 typ.methods = []; 391 typ.methodSetCache = null; 392 typ.comparable = true; 393 return typ; 394 }; 395 396 var $methodSet = function(typ) { 397 if (typ.methodSetCache !== null) { 398 return typ.methodSetCache; 399 } 400 var base = {}; 401 402 var isPtr = (typ.kind === $kindPtr); 403 if (isPtr && typ.elem.kind === $kindInterface) { 404 typ.methodSetCache = []; 405 return []; 406 } 407 408 var current = [{typ: isPtr ? typ.elem : typ, indirect: isPtr}]; 409 410 var seen = {}; 411 412 while (current.length > 0) { 413 var next = []; 414 var mset = []; 415 416 current.forEach(function(e) { 417 if (seen[e.typ.string]) { 418 return; 419 } 420 seen[e.typ.string] = true; 421 422 if (e.typ.named) { 423 mset = mset.concat(e.typ.methods); 424 if (e.indirect) { 425 mset = mset.concat($ptrType(e.typ).methods); 426 } 427 } 428 429 switch (e.typ.kind) { 430 case $kindStruct: 431 e.typ.fields.forEach(function(f) { 432 if (f.embedded) { 433 var fTyp = f.typ; 434 var fIsPtr = (fTyp.kind === $kindPtr); 435 next.push({typ: fIsPtr ? fTyp.elem : fTyp, indirect: e.indirect || fIsPtr}); 436 } 437 }); 438 break; 439 440 case $kindInterface: 441 mset = mset.concat(e.typ.methods); 442 break; 443 } 444 }); 445 446 mset.forEach(function(m) { 447 if (base[m.name] === undefined) { 448 base[m.name] = m; 449 } 450 }); 451 452 current = next; 453 } 454 455 typ.methodSetCache = []; 456 Object.keys(base).sort().forEach(function(name) { 457 typ.methodSetCache.push(base[name]); 458 }); 459 return typ.methodSetCache; 460 }; 461 462 var $Bool = $newType( 1, $kindBool, "bool", true, "", false, null); 463 var $Int = $newType( 4, $kindInt, "int", true, "", false, null); 464 var $Int8 = $newType( 1, $kindInt8, "int8", true, "", false, null); 465 var $Int16 = $newType( 2, $kindInt16, "int16", true, "", false, null); 466 var $Int32 = $newType( 4, $kindInt32, "int32", true, "", false, null); 467 var $Int64 = $newType( 8, $kindInt64, "int64", true, "", false, null); 468 var $Uint = $newType( 4, $kindUint, "uint", true, "", false, null); 469 var $Uint8 = $newType( 1, $kindUint8, "uint8", true, "", false, null); 470 var $Uint16 = $newType( 2, $kindUint16, "uint16", true, "", false, null); 471 var $Uint32 = $newType( 4, $kindUint32, "uint32", true, "", false, null); 472 var $Uint64 = $newType( 8, $kindUint64, "uint64", true, "", false, null); 473 var $Uintptr = $newType( 4, $kindUintptr, "uintptr", true, "", false, null); 474 var $Float32 = $newType( 4, $kindFloat32, "float32", true, "", false, null); 475 var $Float64 = $newType( 8, $kindFloat64, "float64", true, "", false, null); 476 var $Complex64 = $newType( 8, $kindComplex64, "complex64", true, "", false, null); 477 var $Complex128 = $newType(16, $kindComplex128, "complex128", true, "", false, null); 478 var $String = $newType( 8, $kindString, "string", true, "", false, null); 479 var $UnsafePointer = $newType( 4, $kindUnsafePointer, "unsafe.Pointer", true, "", false, null); 480 481 var $nativeArray = function(elemKind) { 482 switch (elemKind) { 483 case $kindInt: 484 return Int32Array; 485 case $kindInt8: 486 return Int8Array; 487 case $kindInt16: 488 return Int16Array; 489 case $kindInt32: 490 return Int32Array; 491 case $kindUint: 492 return Uint32Array; 493 case $kindUint8: 494 return Uint8Array; 495 case $kindUint16: 496 return Uint16Array; 497 case $kindUint32: 498 return Uint32Array; 499 case $kindUintptr: 500 return Uint32Array; 501 case $kindFloat32: 502 return Float32Array; 503 case $kindFloat64: 504 return Float64Array; 505 default: 506 return Array; 507 } 508 }; 509 var $toNativeArray = function(elemKind, array) { 510 var nativeArray = $nativeArray(elemKind); 511 if (nativeArray === Array) { 512 return array; 513 } 514 return new nativeArray(array); 515 }; 516 var $arrayTypes = {}; 517 var $arrayType = function(elem, len) { 518 var typeKey = elem.id + "$" + len; 519 var typ = $arrayTypes[typeKey]; 520 if (typ === undefined) { 521 typ = $newType(elem.size*len, $kindArray, "[" + len + "]" + elem.string, false, "", false, null); 522 $arrayTypes[typeKey] = typ; 523 typ.init(elem, len); 524 } 525 return typ; 526 }; 527 528 var $chanType = function(elem, sendOnly, recvOnly) { 529 var string = (recvOnly ? "<-" : "") + "chan" + (sendOnly ? "<- " : " ") 530 if (!sendOnly && !recvOnly && (elem.string[0] == "<")) { 531 string += "(" + elem.string + ")"; 532 } else { 533 string += elem.string; 534 } 535 var field = sendOnly ? "SendChan" : (recvOnly ? "RecvChan" : "Chan"); 536 var typ = elem[field]; 537 if (typ === undefined) { 538 typ = $newType(4, $kindChan, string, false, "", false, null); 539 elem[field] = typ; 540 typ.init(elem, sendOnly, recvOnly); 541 } 542 return typ; 543 }; 544 var $Chan = function(elem, capacity) { 545 if (capacity < 0 || capacity > 2147483647) { 546 $throwRuntimeError("makechan: size out of range"); 547 } 548 this.$elem = elem; 549 this.$capacity = capacity; 550 this.$buffer = []; 551 this.$sendQueue = []; 552 this.$recvQueue = []; 553 this.$closed = false; 554 }; 555 var $chanNil = new $Chan(null, 0); 556 $chanNil.$sendQueue = $chanNil.$recvQueue = { length: 0, push: function() {}, shift: function() { return undefined; }, indexOf: function() { return -1; } }; 557 558 var $funcTypes = {}; 559 var $funcType = function(params, results, variadic) { 560 var typeKey = $mapArray(params, function(p) { return p.id; }).join(",") + "$" + $mapArray(results, function(r) { return r.id; }).join(",") + "$" + variadic; 561 var typ = $funcTypes[typeKey]; 562 if (typ === undefined) { 563 var paramTypes = $mapArray(params, function(p) { return p.string; }); 564 if (variadic) { 565 paramTypes[paramTypes.length - 1] = "..." + paramTypes[paramTypes.length - 1].substr(2); 566 } 567 var string = "func(" + paramTypes.join(", ") + ")"; 568 if (results.length === 1) { 569 string += " " + results[0].string; 570 } else if (results.length > 1) { 571 string += " (" + $mapArray(results, function(r) { return r.string; }).join(", ") + ")"; 572 } 573 typ = $newType(4, $kindFunc, string, false, "", false, null); 574 $funcTypes[typeKey] = typ; 575 typ.init(params, results, variadic); 576 } 577 return typ; 578 }; 579 580 var $interfaceTypes = {}; 581 var $interfaceType = function(methods) { 582 var typeKey = $mapArray(methods, function(m) { return m.pkg + "," + m.name + "," + m.typ.id; }).join("$"); 583 var typ = $interfaceTypes[typeKey]; 584 if (typ === undefined) { 585 var string = "interface {}"; 586 if (methods.length !== 0) { 587 string = "interface { " + $mapArray(methods, function(m) { 588 return (m.pkg !== "" ? m.pkg + "." : "") + m.name + m.typ.string.substr(4); 589 }).join("; ") + " }"; 590 } 591 typ = $newType(8, $kindInterface, string, false, "", false, null); 592 $interfaceTypes[typeKey] = typ; 593 typ.init(methods); 594 } 595 return typ; 596 }; 597 var $emptyInterface = $interfaceType([]); 598 var $ifaceNil = {}; 599 var $error = $newType(8, $kindInterface, "error", true, "", false, null); 600 $error.init([{prop: "Error", name: "Error", pkg: "", typ: $funcType([], [$String], false)}]); 601 602 var $mapTypes = {}; 603 var $mapType = function(key, elem) { 604 var typeKey = key.id + "$" + elem.id; 605 var typ = $mapTypes[typeKey]; 606 if (typ === undefined) { 607 typ = $newType(4, $kindMap, "map[" + key.string + "]" + elem.string, false, "", false, null); 608 $mapTypes[typeKey] = typ; 609 typ.init(key, elem); 610 } 611 return typ; 612 }; 613 var $makeMap = function(keyForFunc, entries) { 614 var m = {}; 615 for (var i = 0; i < entries.length; i++) { 616 var e = entries[i]; 617 m[keyForFunc(e.k)] = e; 618 } 619 return m; 620 }; 621 622 var $ptrType = function(elem) { 623 var typ = elem.ptr; 624 if (typ === undefined) { 625 typ = $newType(4, $kindPtr, "*" + elem.string, false, "", elem.exported, null); 626 elem.ptr = typ; 627 typ.init(elem); 628 } 629 return typ; 630 }; 631 632 var $newDataPointer = function(data, constructor) { 633 if (constructor.elem.kind === $kindStruct) { 634 return data; 635 } 636 return new constructor(function() { return data; }, function(v) { data = v; }); 637 }; 638 639 var $indexPtr = function(array, index, constructor) { 640 array.$ptr = array.$ptr || {}; 641 return array.$ptr[index] || (array.$ptr[index] = new constructor(function() { return array[index]; }, function(v) { array[index] = v; })); 642 }; 643 644 var $sliceType = function(elem) { 645 var typ = elem.slice; 646 if (typ === undefined) { 647 typ = $newType(12, $kindSlice, "[]" + elem.string, false, "", false, null); 648 elem.slice = typ; 649 typ.init(elem); 650 } 651 return typ; 652 }; 653 var $makeSlice = function(typ, length, capacity) { 654 capacity = capacity || length; 655 if (length < 0 || length > 2147483647) { 656 $throwRuntimeError("makeslice: len out of range"); 657 } 658 if (capacity < 0 || capacity < length || capacity > 2147483647) { 659 $throwRuntimeError("makeslice: cap out of range"); 660 } 661 var array = new typ.nativeArray(capacity); 662 if (typ.nativeArray === Array) { 663 for (var i = 0; i < capacity; i++) { 664 array[i] = typ.elem.zero(); 665 } 666 } 667 var slice = new typ(array); 668 slice.$length = length; 669 return slice; 670 }; 671 672 var $structTypes = {}; 673 var $structType = function(pkgPath, fields) { 674 var typeKey = $mapArray(fields, function(f) { return f.name + "," + f.typ.id + "," + f.tag; }).join("$"); 675 var typ = $structTypes[typeKey]; 676 if (typ === undefined) { 677 var string = "struct { " + $mapArray(fields, function(f) { 678 var str = f.typ.string + (f.tag !== "" ? (" \"" + f.tag.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\"") : ""); 679 if (f.embedded) { 680 return str 681 } 682 return f.name + " " + str 683 }).join("; ") + " }"; 684 if (fields.length === 0) { 685 string = "struct {}"; 686 } 687 typ = $newType(0, $kindStruct, string, false, "", false, function() { 688 this.$val = this; 689 for (var i = 0; i < fields.length; i++) { 690 var f = fields[i]; 691 var arg = arguments[i]; 692 this[f.prop] = arg !== undefined ? arg : f.typ.zero(); 693 } 694 }); 695 $structTypes[typeKey] = typ; 696 typ.init(pkgPath, fields); 697 } 698 return typ; 699 }; 700 701 var $assertType = function(value, type, returnTuple) { 702 var isInterface = (type.kind === $kindInterface), ok, missingMethod = ""; 703 if (value === $ifaceNil) { 704 ok = false; 705 } else if (!isInterface) { 706 ok = value.constructor === type; 707 } else { 708 var valueTypeString = value.constructor.string; 709 ok = type.implementedBy[valueTypeString]; 710 if (ok === undefined) { 711 ok = true; 712 var valueMethodSet = $methodSet(value.constructor); 713 var interfaceMethods = type.methods; 714 for (var i = 0; i < interfaceMethods.length; i++) { 715 var tm = interfaceMethods[i]; 716 var found = false; 717 for (var j = 0; j < valueMethodSet.length; j++) { 718 var vm = valueMethodSet[j]; 719 if (vm.name === tm.name && vm.pkg === tm.pkg && vm.typ === tm.typ) { 720 found = true; 721 break; 722 } 723 } 724 if (!found) { 725 ok = false; 726 type.missingMethodFor[valueTypeString] = tm.name; 727 break; 728 } 729 } 730 type.implementedBy[valueTypeString] = ok; 731 } 732 if (!ok) { 733 missingMethod = type.missingMethodFor[valueTypeString]; 734 } 735 } 736 737 if (!ok) { 738 if (returnTuple) { 739 return [type.zero(), false]; 740 } 741 $panic(new $packages["runtime"].TypeAssertionError.ptr( 742 $packages["runtime"]._type.ptr.nil, 743 (value === $ifaceNil ? $packages["runtime"]._type.ptr.nil : new $packages["runtime"]._type.ptr(value.constructor.string)), 744 new $packages["runtime"]._type.ptr(type.string), 745 missingMethod)); 746 } 747 748 if (!isInterface) { 749 value = value.$val; 750 } 751 if (type === $jsObjectPtr) { 752 value = value.object; 753 } 754 return returnTuple ? [value, true] : value; 755 }; 756 `