github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/prelude/jsmapping.go (about) 1 package prelude 2 3 const jsmapping = ` 4 var $jsObjectPtr, $jsErrorPtr; 5 6 var $needsExternalization = function(t) { 7 switch (t.kind) { 8 case $kindBool: 9 case $kindInt: 10 case $kindInt8: 11 case $kindInt16: 12 case $kindInt32: 13 case $kindUint: 14 case $kindUint8: 15 case $kindUint16: 16 case $kindUint32: 17 case $kindUintptr: 18 case $kindFloat32: 19 case $kindFloat64: 20 return false; 21 default: 22 return t !== $jsObjectPtr; 23 } 24 }; 25 26 var $externalize = function(v, t) { 27 if (t === $jsObjectPtr) { 28 return v; 29 } 30 switch (t.kind) { 31 case $kindBool: 32 case $kindInt: 33 case $kindInt8: 34 case $kindInt16: 35 case $kindInt32: 36 case $kindUint: 37 case $kindUint8: 38 case $kindUint16: 39 case $kindUint32: 40 case $kindUintptr: 41 case $kindFloat32: 42 case $kindFloat64: 43 return v; 44 case $kindInt64: 45 case $kindUint64: 46 return $flatten64(v); 47 case $kindArray: 48 if ($needsExternalization(t.elem)) { 49 return $mapArray(v, function(e) { return $externalize(e, t.elem); }); 50 } 51 return v; 52 case $kindFunc: 53 return $externalizeFunction(v, t, false); 54 case $kindInterface: 55 if (v === $ifaceNil) { 56 return null; 57 } 58 if (v.constructor === $jsObjectPtr) { 59 return v.$val.object; 60 } 61 return $externalize(v.$val, v.constructor); 62 case $kindMap: 63 var m = {}; 64 var keys = $keys(v); 65 for (var i = 0; i < keys.length; i++) { 66 var entry = v[keys[i]]; 67 m[$externalize(entry.k, t.key)] = $externalize(entry.v, t.elem); 68 } 69 return m; 70 case $kindPtr: 71 if (v === t.nil) { 72 return null; 73 } 74 return $externalize(v.$get(), t.elem); 75 case $kindSlice: 76 if ($needsExternalization(t.elem)) { 77 return $mapArray($sliceToArray(v), function(e) { return $externalize(e, t.elem); }); 78 } 79 return $sliceToArray(v); 80 case $kindString: 81 if ($isASCII(v)) { 82 return v; 83 } 84 var s = "", r; 85 for (var i = 0; i < v.length; i += r[1]) { 86 r = $decodeRune(v, i); 87 var c = r[0]; 88 if (c > 0xFFFF) { 89 var h = Math.floor((c - 0x10000) / 0x400) + 0xD800; 90 var l = (c - 0x10000) % 0x400 + 0xDC00; 91 s += String.fromCharCode(h, l); 92 continue; 93 } 94 s += String.fromCharCode(c); 95 } 96 return s; 97 case $kindStruct: 98 var timePkg = $packages["time"]; 99 if (timePkg !== undefined && v.constructor === timePkg.Time.ptr) { 100 var milli = $div64(v.UnixNano(), new $Int64(0, 1000000)); 101 return new Date($flatten64(milli)); 102 } 103 104 var noJsObject = {}; 105 var searchJsObject = function(v, t) { 106 if (t === $jsObjectPtr) { 107 return v; 108 } 109 switch (t.kind) { 110 case $kindPtr: 111 if (v === t.nil) { 112 return noJsObject; 113 } 114 return searchJsObject(v.$get(), t.elem); 115 case $kindStruct: 116 var f = t.fields[0]; 117 return searchJsObject(v[f.prop], f.typ); 118 case $kindInterface: 119 return searchJsObject(v.$val, v.constructor); 120 default: 121 return noJsObject; 122 } 123 }; 124 var o = searchJsObject(v, t); 125 if (o !== noJsObject) { 126 return o; 127 } 128 129 o = {}; 130 for (var i = 0; i < t.fields.length; i++) { 131 var f = t.fields[i]; 132 if (!f.exported) { 133 continue; 134 } 135 o[f.name] = $externalize(v[f.prop], f.typ); 136 } 137 return o; 138 } 139 $throwRuntimeError("cannot externalize " + t.string); 140 }; 141 142 var $externalizeFunction = function(v, t, passThis) { 143 if (v === $throwNilPointerError) { 144 return null; 145 } 146 if (v.$externalizeWrapper === undefined) { 147 $checkForDeadlock = false; 148 v.$externalizeWrapper = function() { 149 var args = []; 150 for (var i = 0; i < t.params.length; i++) { 151 if (t.variadic && i === t.params.length - 1) { 152 var vt = t.params[i].elem, varargs = []; 153 for (var j = i; j < arguments.length; j++) { 154 varargs.push($internalize(arguments[j], vt)); 155 } 156 args.push(new (t.params[i])(varargs)); 157 break; 158 } 159 args.push($internalize(arguments[i], t.params[i])); 160 } 161 var result = v.apply(passThis ? this : undefined, args); 162 switch (t.results.length) { 163 case 0: 164 return; 165 case 1: 166 return $externalize(result, t.results[0]); 167 default: 168 for (var i = 0; i < t.results.length; i++) { 169 result[i] = $externalize(result[i], t.results[i]); 170 } 171 return result; 172 } 173 }; 174 } 175 return v.$externalizeWrapper; 176 }; 177 178 var $internalize = function(v, t, recv) { 179 if (t === $jsObjectPtr) { 180 return v; 181 } 182 if (t === $jsObjectPtr.elem) { 183 $throwRuntimeError("cannot internalize js.Object, use *js.Object instead"); 184 } 185 if (v && v.__internal_object__ !== undefined) { 186 return $assertType(v.__internal_object__, t, false); 187 } 188 var timePkg = $packages["time"]; 189 if (timePkg !== undefined && t === timePkg.Time) { 190 if (!(v !== null && v !== undefined && v.constructor === Date)) { 191 $throwRuntimeError("cannot internalize time.Time from " + typeof v + ", must be Date"); 192 } 193 return timePkg.Unix(new $Int64(0, 0), new $Int64(0, v.getTime() * 1000000)); 194 } 195 switch (t.kind) { 196 case $kindBool: 197 return !!v; 198 case $kindInt: 199 return parseInt(v); 200 case $kindInt8: 201 return parseInt(v) << 24 >> 24; 202 case $kindInt16: 203 return parseInt(v) << 16 >> 16; 204 case $kindInt32: 205 return parseInt(v) >> 0; 206 case $kindUint: 207 return parseInt(v); 208 case $kindUint8: 209 return parseInt(v) << 24 >>> 24; 210 case $kindUint16: 211 return parseInt(v) << 16 >>> 16; 212 case $kindUint32: 213 case $kindUintptr: 214 return parseInt(v) >>> 0; 215 case $kindInt64: 216 case $kindUint64: 217 return new t(0, v); 218 case $kindFloat32: 219 case $kindFloat64: 220 return parseFloat(v); 221 case $kindArray: 222 if (v.length !== t.len) { 223 $throwRuntimeError("got array with wrong size from JavaScript native"); 224 } 225 return $mapArray(v, function(e) { return $internalize(e, t.elem); }); 226 case $kindFunc: 227 return function() { 228 var args = []; 229 for (var i = 0; i < t.params.length; i++) { 230 if (t.variadic && i === t.params.length - 1) { 231 var vt = t.params[i].elem, varargs = arguments[i]; 232 for (var j = 0; j < varargs.$length; j++) { 233 args.push($externalize(varargs.$array[varargs.$offset + j], vt)); 234 } 235 break; 236 } 237 args.push($externalize(arguments[i], t.params[i])); 238 } 239 var result = v.apply(recv, args); 240 switch (t.results.length) { 241 case 0: 242 return; 243 case 1: 244 return $internalize(result, t.results[0]); 245 default: 246 for (var i = 0; i < t.results.length; i++) { 247 result[i] = $internalize(result[i], t.results[i]); 248 } 249 return result; 250 } 251 }; 252 case $kindInterface: 253 if (t.methods.length !== 0) { 254 $throwRuntimeError("cannot internalize " + t.string); 255 } 256 if (v === null) { 257 return $ifaceNil; 258 } 259 if (v === undefined) { 260 return new $jsObjectPtr(undefined); 261 } 262 switch (v.constructor) { 263 case Int8Array: 264 return new ($sliceType($Int8))(v); 265 case Int16Array: 266 return new ($sliceType($Int16))(v); 267 case Int32Array: 268 return new ($sliceType($Int))(v); 269 case Uint8Array: 270 return new ($sliceType($Uint8))(v); 271 case Uint16Array: 272 return new ($sliceType($Uint16))(v); 273 case Uint32Array: 274 return new ($sliceType($Uint))(v); 275 case Float32Array: 276 return new ($sliceType($Float32))(v); 277 case Float64Array: 278 return new ($sliceType($Float64))(v); 279 case Array: 280 return $internalize(v, $sliceType($emptyInterface)); 281 case Boolean: 282 return new $Bool(!!v); 283 case Date: 284 if (timePkg === undefined) { 285 /* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */ 286 return new $jsObjectPtr(v); 287 } 288 return new timePkg.Time($internalize(v, timePkg.Time)); 289 case Function: 290 var funcType = $funcType([$sliceType($emptyInterface)], [$jsObjectPtr], true); 291 return new funcType($internalize(v, funcType)); 292 case Number: 293 return new $Float64(parseFloat(v)); 294 case String: 295 return new $String($internalize(v, $String)); 296 default: 297 if ($global.Node && v instanceof $global.Node) { 298 return new $jsObjectPtr(v); 299 } 300 var mapType = $mapType($String, $emptyInterface); 301 return new mapType($internalize(v, mapType)); 302 } 303 case $kindMap: 304 var m = {}; 305 var keys = $keys(v); 306 for (var i = 0; i < keys.length; i++) { 307 var k = $internalize(keys[i], t.key); 308 m[t.key.keyFor(k)] = { k: k, v: $internalize(v[keys[i]], t.elem) }; 309 } 310 return m; 311 case $kindPtr: 312 if (t.elem.kind === $kindStruct) { 313 return $internalize(v, t.elem); 314 } 315 case $kindSlice: 316 return new t($mapArray(v, function(e) { return $internalize(e, t.elem); })); 317 case $kindString: 318 v = String(v); 319 if ($isASCII(v)) { 320 return v; 321 } 322 var s = ""; 323 var i = 0; 324 while (i < v.length) { 325 var h = v.charCodeAt(i); 326 if (0xD800 <= h && h <= 0xDBFF) { 327 var l = v.charCodeAt(i + 1); 328 var c = (h - 0xD800) * 0x400 + l - 0xDC00 + 0x10000; 329 s += $encodeRune(c); 330 i += 2; 331 continue; 332 } 333 s += $encodeRune(h); 334 i++; 335 } 336 return s; 337 case $kindStruct: 338 var noJsObject = {}; 339 var searchJsObject = function(t) { 340 if (t === $jsObjectPtr) { 341 return v; 342 } 343 if (t === $jsObjectPtr.elem) { 344 $throwRuntimeError("cannot internalize js.Object, use *js.Object instead"); 345 } 346 switch (t.kind) { 347 case $kindPtr: 348 return searchJsObject(t.elem); 349 case $kindStruct: 350 var f = t.fields[0]; 351 var o = searchJsObject(f.typ); 352 if (o !== noJsObject) { 353 var n = new t.ptr(); 354 n[f.prop] = o; 355 return n; 356 } 357 return noJsObject; 358 default: 359 return noJsObject; 360 } 361 }; 362 var o = searchJsObject(t); 363 if (o !== noJsObject) { 364 return o; 365 } 366 } 367 $throwRuntimeError("cannot internalize " + t.string); 368 }; 369 370 /* $isASCII reports whether string s contains only ASCII characters. */ 371 var $isASCII = function(s) { 372 for (var i = 0; i < s.length; i++) { 373 if (s.charCodeAt(i) >= 128) { 374 return false; 375 } 376 } 377 return true; 378 }; 379 `