@live-codes/pascal-wasm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +501 -0
  2. package/README.md +278 -0
  3. package/THIRD-PARTY-NOTICES.md +48 -0
  4. package/assets/pas2js.wasm +0 -0
  5. package/assets/rtl/Rtl.BrowserLoadHelper.pas +179 -0
  6. package/assets/rtl/browserconsole.pas +190 -0
  7. package/assets/rtl/classes.pas +11371 -0
  8. package/assets/rtl/js.pas +2211 -0
  9. package/assets/rtl/manifest.json +19 -0
  10. package/assets/rtl/math.pas +903 -0
  11. package/assets/rtl/p2jsres.pp +334 -0
  12. package/assets/rtl/rtl.js +1563 -0
  13. package/assets/rtl/rtlconsts.pas +97 -0
  14. package/assets/rtl/simplelinkedlist.pas +152 -0
  15. package/assets/rtl/system.pas +1166 -0
  16. package/assets/rtl/sysutils.pas +8959 -0
  17. package/assets/rtl/types.pas +2296 -0
  18. package/assets/rtl/typinfo.pas +1680 -0
  19. package/assets/rtl/web.pas +3586 -0
  20. package/assets/rtl/weborworker.pas +2101 -0
  21. package/dist/pascal-wasm.iife.min.js +6 -0
  22. package/dist/pascal-wasm.iife.min.js.map +7 -0
  23. package/package.json +54 -0
  24. package/src/assets.js +119 -0
  25. package/src/compiler.js +142 -0
  26. package/src/config.js +24 -0
  27. package/src/iife.js +27 -0
  28. package/src/index.js +130 -0
  29. package/src/vendor/browser_wasi_shim/debug.js +1 -0
  30. package/src/vendor/browser_wasi_shim/fd.js +1 -0
  31. package/src/vendor/browser_wasi_shim/fs_mem.js +1 -0
  32. package/src/vendor/browser_wasi_shim/fs_opfs.js +1 -0
  33. package/src/vendor/browser_wasi_shim/index.js +1 -0
  34. package/src/vendor/browser_wasi_shim/strace.js +1 -0
  35. package/src/vendor/browser_wasi_shim/wasi.js +1 -0
  36. package/src/vendor/browser_wasi_shim/wasi_defs.js +1 -0
  37. package/types/index.d.ts +89 -0
@@ -0,0 +1,1166 @@
1
+ {
2
+ This file is part of the Pas2JS run time library.
3
+ Copyright (c) 2018 by Mattias Gaertner
4
+
5
+ See the file COPYING.FPC, included in this distribution,
6
+ for details about the copyright.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
+
12
+ **********************************************************************}
13
+ unit System;
14
+
15
+ {$mode objfpc}
16
+ {$modeswitch externalclass}
17
+
18
+ interface
19
+
20
+ {$IFDEF NodeJS}
21
+ var
22
+ LineEnding: string = #10;
23
+ sLineBreak: string = #10;
24
+ {$ELSE}
25
+ const
26
+ LineEnding = #10;
27
+ sLineBreak = LineEnding;
28
+ {$ENDIF}
29
+
30
+ Var
31
+ PathDelim : Char = '/';
32
+ AllowDirectorySeparators : Set of Char = ['/'];
33
+ AllowDriveSeparators : Set of Char = [':'];
34
+ ExtensionSeparator : Char = '.';
35
+
36
+ const
37
+ MaxSmallint = 32767;
38
+ MinSmallint = -32768;
39
+ MaxShortInt = 127;
40
+ MinShortInt = -128;
41
+ MaxByte = $FF;
42
+ MaxWord = $FFFF;
43
+ MaxLongint = $7fffffff;
44
+ MaxCardinal = LongWord($ffffffff);
45
+
46
+ Maxint = MaxLongint;
47
+ IsMultiThread = false;
48
+
49
+ {*****************************************************************************
50
+ Base types
51
+ *****************************************************************************}
52
+ type
53
+ HRESULT = Longint; // For Delphi compatibility
54
+ Int8 = ShortInt;
55
+ UInt8 = Byte;
56
+ Int16 = SmallInt;
57
+ UInt16 = Word;
58
+ Int32 = Longint;
59
+ UInt32 = LongWord;
60
+
61
+ Integer = LongInt;
62
+ Cardinal = LongWord;
63
+ DWord = LongWord;
64
+ SizeInt = NativeInt;
65
+ SizeUInt = NativeUInt;
66
+ PtrInt = NativeInt;
67
+ PtrUInt = NativeUInt;
68
+ ValSInt = NativeInt;
69
+ ValUInt = NativeUInt;
70
+ CodePointer = Pointer;
71
+ ValReal = Double;
72
+ Real = type Double;
73
+ Extended = type Double;
74
+
75
+ TDateTime = type double;
76
+ TTime = type TDateTime;
77
+ TDate = type TDateTime;
78
+
79
+ Int64 = type NativeInt unimplemented; // only 53 bits at runtime
80
+ UInt64 = type NativeUInt unimplemented; // only 52 bits at runtime
81
+ QWord = type NativeUInt unimplemented; // only 52 bits at runtime
82
+ Single = type Double unimplemented;
83
+ Comp = type NativeInt unimplemented;
84
+ NativeLargeInt = NativeInt;
85
+ NativeLargeUInt = NativeUInt;
86
+
87
+ UnicodeChar = Char;
88
+ UnicodeString = type String;
89
+ WideString = type String;
90
+ WideChar = Char;
91
+
92
+ TDynArrayIndex = NativeInt;
93
+ TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
94
+
95
+ TCompareOption = ({coLingIgnoreCase, coLingIgnoreDiacritic, }coIgnoreCase{,
96
+ coIgnoreKanaType, coIgnoreNonSpace, coIgnoreSymbols, coIgnoreWidth,
97
+ coLingCasing, coDigitAsNumbers, coStringSort});
98
+ TCompareOptions = set of TCompareOption;
99
+
100
+ generic TArray<T> = array of T;
101
+
102
+ {*****************************************************************************
103
+ TObject, TClass, IUnknown, IInterface, TInterfacedObject
104
+ *****************************************************************************}
105
+
106
+ type
107
+ TGuid = record
108
+ D1: DWord;
109
+ D2: word;
110
+ D3: word;
111
+ D4: array[0..7] of byte;
112
+ end;
113
+ TGUIDString = type string;
114
+
115
+ TMethod = record
116
+ Code : CodePointer;
117
+ Data : Pointer;
118
+ end;
119
+
120
+ PMethod = ^TMethod;
121
+
122
+ TClass = class of TObject;
123
+
124
+ { TObject }
125
+ {$IFDEF ENABLE_DELPHI_RTTI}
126
+ {$RTTI INHERIT
127
+ METHODS([vcPublic, vcPublished])
128
+ FIELDS([vcPrivate,vcProtected, vcPublic,vcPublished])
129
+ PROPERTIES([vcPublic, vcPublished])
130
+ }
131
+ {$ENDIF}
132
+
133
+ {$DispatchField Msg} // enable checking message methods for record field name "Msg"
134
+ {$DispatchStrField MsgStr}
135
+ TObject = class
136
+ private
137
+ class var FClassName: String; external name '$classname';
138
+ class var FClassParent: TClass; external name '$ancestor';
139
+ class var FUnitName: String; external name '$module.$name';
140
+ public
141
+ constructor Create;
142
+ destructor Destroy; virtual;
143
+
144
+ // Free is using compiler magic.
145
+ // Reasons:
146
+ // 1. In JS calling obj.Free when obj=nil would crash.
147
+ // 2. In JS freeing memory requires to set all references to nil.
148
+ // Therefore any obj.free call is replaced by the compiler with some rtl magic.
149
+ procedure Free;
150
+
151
+ class function ClassType: TClass; assembler;
152
+ class property ClassName: String read FClassName;
153
+ class function ClassNameIs(const Name: string): boolean;
154
+ class property ClassParent: TClass read FClassParent;
155
+ class function InheritsFrom(aClass: TClass): boolean; assembler;
156
+ class property UnitName: String read FUnitName;
157
+ Class function MethodName(aCode : Pointer) : String;
158
+ Class function MethodAddress(aName : String) : Pointer;
159
+ Class Function FieldAddress(aName : String) : Pointer;
160
+ Class Function ClassInfo : Pointer;
161
+ class function QualifiedClassName: String;
162
+
163
+ procedure AfterConstruction; virtual;
164
+ procedure BeforeDestruction; virtual;
165
+
166
+ // message handling routines
167
+ procedure Dispatch(var aMessage); virtual;
168
+ procedure DispatchStr(var aMessage); virtual;
169
+ procedure DefaultHandler(var aMessage); virtual;
170
+ procedure DefaultHandlerStr(var aMessage); virtual;
171
+
172
+ function GetInterface(const iid: TGuid; out obj): boolean;
173
+ function GetInterface(const iidstr: String; out obj): boolean; inline;
174
+ function GetInterfaceByStr(const iidstr: String; out obj): boolean;
175
+ function GetInterfaceWeak(const iid: TGuid; out obj): boolean; // equal to GetInterface but the interface returned is not referenced
176
+
177
+ function Equals(Obj: TObject): boolean; virtual;
178
+ function ToString: String; virtual;
179
+ end;
180
+
181
+ { TCustomAttribute - base class of all user defined attributes. }
182
+
183
+ TCustomAttribute = class
184
+ end;
185
+ TCustomAttributeClass = class of TCustomAttribute;
186
+ TCustomAttributeArray = array of TCustomAttribute;
187
+
188
+ const
189
+ { IInterface }
190
+ S_OK = 0;
191
+ S_FALSE = 1;
192
+ E_NOINTERFACE = -2147467262; // FPC: longint($80004002)
193
+ E_UNEXPECTED = -2147418113; // FPC: longint($8000FFFF)
194
+ E_NOTIMPL = -2147467263; // FPC: longint($80004001)
195
+
196
+ type
197
+ {$Interfaces COM}
198
+ IUnknown = interface
199
+ ['{00000000-0000-0000-C000-000000000046}']
200
+ function QueryInterface(const iid: TGuid; out obj): Integer;
201
+ function _AddRef: Integer;
202
+ function _Release: Integer;
203
+ end;
204
+ IInterface = IUnknown;
205
+
206
+ {$M+}
207
+ IInvokable = interface(IInterface)
208
+ end;
209
+ {$M-}
210
+
211
+ { Enumerator support }
212
+ IEnumerator = interface(IInterface)
213
+ function GetCurrent: TObject;
214
+ function MoveNext: Boolean;
215
+ procedure Reset;
216
+ property Current: TObject read GetCurrent;
217
+ end;
218
+
219
+ IEnumerable = interface(IInterface)
220
+ function GetEnumerator: IEnumerator;
221
+ end;
222
+
223
+ { TInterfacedObject }
224
+
225
+ TInterfacedObject = class(TObject,IUnknown)
226
+ protected
227
+ fRefCount: Integer;
228
+ { implement methods of IUnknown }
229
+ function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
230
+ function _AddRef: Integer; virtual;
231
+ function _Release: Integer; virtual;
232
+ public
233
+ procedure BeforeDestruction; override;
234
+ property RefCount: Integer read fRefCount;
235
+ end;
236
+ TInterfacedClass = class of TInterfacedObject;
237
+
238
+ { TAggregatedObject - sub or satellite object using same interface as controller }
239
+
240
+ TAggregatedObject = class(TObject)
241
+ private
242
+ fController: Pointer;
243
+ function GetController: IUnknown;
244
+ protected
245
+ { implement methods of IUnknown }
246
+ function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
247
+ function _AddRef: Integer; virtual;
248
+ function _Release: Integer; virtual;
249
+ public
250
+ constructor Create(const aController: IUnknown); reintroduce;
251
+ property Controller: IUnknown read GetController;
252
+ end;
253
+
254
+ { TContainedObject }
255
+
256
+ TContainedObject = class(TAggregatedObject,IInterface)
257
+ protected
258
+ function QueryInterface(const iid: TGuid; out obj): Integer; override;
259
+ end;
260
+
261
+ const
262
+ { for safe as operator support }
263
+ IObjectInstance: TGuid = '{D91C9AF4-3C93-420F-A303-BF5BA82BFD23}';
264
+
265
+ function GUIDToString(const GUID: TGUID): string; external name 'rtl.guidrToStr';
266
+
267
+ {*****************************************************************************
268
+ RTTI support
269
+ *****************************************************************************}
270
+ type
271
+ // if you change the following enumeration type in any way
272
+ // you also have to change the rtl.js in an appropriate way !
273
+ TTypeKind = (
274
+ tkUnknown, // 0
275
+ tkInteger, // 1
276
+ tkChar, // 2 in Delphi/FPC tkWChar, tkUChar
277
+ tkString, // 3 in Delphi/FPC tkSString, tkWString or tkUString
278
+ tkEnumeration, // 4
279
+ tkSet, // 5
280
+ tkDouble, // 6
281
+ tkBool, // 7
282
+ tkProcVar, // 8 function or procedure
283
+ tkMethod, // 9 proc var of object
284
+ tkArray, // 10 static array
285
+ tkDynArray, // 11
286
+ tkRecord, // 12
287
+ tkClass, // 13
288
+ tkClassRef, // 14
289
+ tkPointer, // 15
290
+ tkJSValue, // 16
291
+ tkRefToProcVar, // 17 variable of procedure type
292
+ tkInterface, // 18
293
+ //tkObject,
294
+ //tkSString,tkLString,tkAString,tkWString,
295
+ //tkVariant,
296
+ //tkWChar,
297
+ //tkInt64,
298
+ //tkQWord,
299
+ //tkInterfaceRaw,
300
+ //tkUString,tkUChar,
301
+ tkHelper, // 19
302
+ //tkFile,
303
+ tkExtClass // 20
304
+ );
305
+ TTypeKinds = set of TTypeKind;
306
+
307
+ const
308
+ tkFloat = tkDouble; // for compatibility with Delphi/FPC
309
+ tkProcedure = tkProcVar; // for compatibility with Delphi
310
+ tkAny = [Low(TTypeKind)..High(TTypeKind)];
311
+ tkMethods = [tkMethod];
312
+ tkProperties = tkAny-tkMethods-[tkUnknown];
313
+
314
+ {*****************************************************************************
315
+ Array of const support
316
+ *****************************************************************************}
317
+
318
+ const
319
+ vtInteger = 0;
320
+ vtBoolean = 1;
321
+ //vtChar = 2; // Delphi/FPC: ansichar
322
+ vtExtended = 3; // Note: double in pas2js, PExtended in Delphi/FPC
323
+ //vtString = 4; // Delphi/FPC: PShortString
324
+ vtPointer = 5;
325
+ //vtPChar = 6;
326
+ vtObject = 7;
327
+ vtClass = 8;
328
+ vtWideChar = 9;
329
+ //vtPWideChar = 10;
330
+ //vtAnsiString = 11;
331
+ vtCurrency = 12; // Note: currency in pas2js, PCurrency in Delphi/FPC
332
+ //vtVariant = 13;
333
+ vtInterface = 14;
334
+ //vtWideString = 15;
335
+ //vtInt64 = 16;
336
+ //vtQWord = 17;
337
+ vtUnicodeString = 18;
338
+ // only pas2js, not in Delphi/FPC:
339
+ vtNativeInt = 19;
340
+ vtJSValue = 20;
341
+
342
+ type
343
+ PVarRec = ^TVarRec;
344
+ TVarRec = record
345
+ VType: byte;
346
+ VJSValue: JSValue;
347
+ VInteger: LongInt external name 'VJSValue';
348
+ VBoolean: Boolean external name 'VJSValue';
349
+ VExtended: Double external name 'VJSValue';
350
+ VPointer: Pointer external name 'VJSValue';
351
+ VObject: TObject external name 'VJSValue';
352
+ VClass: TClass external name 'VJSValue';
353
+ VWideChar: WideChar external name 'VJSValue';
354
+ VCurrency: Currency external name 'VJSValue';
355
+ VInterface: Pointer external name 'VJSValue';
356
+ VUnicodeString: UnicodeString external name 'VJSValue';
357
+ VNativeInt: NativeInt external name 'VJSValue';
358
+ end;
359
+ TVarRecArray = array of TVarRec;
360
+
361
+ function VarRecs: TVarRecArray; varargs;
362
+
363
+ {*****************************************************************************
364
+ Init / Exit / ExitProc
365
+ *****************************************************************************}
366
+ var
367
+ ExitCode: Integer; external name 'rtl.exitcode';
368
+ IsConsole: Boolean = {$IFDEF NodeJS}true{$ELSE}false{$ENDIF};
369
+ FirstDotAtFileNameStartIsExtension : Boolean = False;
370
+
371
+ type
372
+ TOnParamCount = function: Longint;
373
+ TOnParamStr = function(Index: Longint): String;
374
+ var
375
+ OnParamCount: TOnParamCount;
376
+ OnParamStr: TOnParamStr;
377
+
378
+ function ParamCount: Longint;
379
+ function ParamStr(Index: Longint): String;
380
+
381
+ {*****************************************************************************
382
+ Math
383
+ *****************************************************************************}
384
+ const
385
+ PI: Double; external name 'Math.PI';
386
+ MathE: Double; external name 'Math.E'; // Euler's number
387
+ MathLN10: Double; external name 'Math.LN10'; // ln(10)
388
+ MathLN2: Double; external name 'Math.LN2'; // ln(2)
389
+ MathLog10E: Double; external name 'Math.LOG10E'; // log10(e)
390
+ MathLog2E: Double; external name 'Math.LOG2E'; // log2(e)
391
+ MathSQRT1_2: Double; external name 'Math.SQRT1_2'; // sqrt(0.5)
392
+ MathSQRT2: Double; external name 'Math.SQRT2'; // sqrt(2)
393
+
394
+ function Abs(const A: integer): integer; overload; external name 'Math.abs';
395
+ function Abs(const A: NativeInt): integer; overload; external name 'Math.abs';
396
+ function Abs(const A: Double): Double; overload; external name 'Math.abs';
397
+ function ArcTan(const A: Double): Double; external name 'Math.atan';
398
+ function ArcTan2(const A,B: Double): Double; external name 'Math.atan2';
399
+ function Cos(const A: Double): Double; external name 'Math.cos';
400
+ function Exp(const A: Double): Double; external name 'Math.exp';
401
+ function Frac(const A: Double): Double; assembler;
402
+ function Ln(const A: Double): Double; external name 'Math.log';
403
+ function Odd(const A: Integer): Boolean; assembler;
404
+ function Random(const Range: Integer): Integer; overload; assembler;
405
+ function Random: Double; overload; external name 'Math.random';
406
+ function Round(const A: Double): NativeInt; external name 'Math.round';
407
+ function Sin(const A: Double): Double; external name 'Math.sin';
408
+ function Sqr(const A: Integer): Integer; assembler; overload;
409
+ function Sqr(const A: Double): Double; assembler; overload;
410
+ function sqrt(const A: Double): Double; external name 'Math.sqrt';
411
+ function Trunc(const A: Double): NativeInt;
412
+
413
+ {*****************************************************************************
414
+ String functions
415
+ *****************************************************************************}
416
+ const
417
+ DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
418
+
419
+ function Int(const A: Double): double;
420
+ function Copy(const S: string; Index, Size: Integer): String; assembler; overload;
421
+ function Copy(const S: string; Index: Integer): String; assembler; overload;
422
+ procedure Delete(var S: String; Index, Size: Integer); overload;
423
+ function Pos(const Search, InString: String): Integer; assembler; overload;
424
+ function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
425
+ procedure Insert(const Insertion: String; var Target: String; Index: Integer); overload;
426
+ function upcase(c : char) : char; assembler;
427
+ function HexStr(Val: NativeInt; cnt: byte): string; external name 'rtl.hexStr'; overload;
428
+ function binstr(val : NativeUInt; cnt : byte) : string;
429
+
430
+ procedure val(const S: String; out NI : NativeInt; out Code: Integer); overload;
431
+ procedure val(const S: String; out NI : NativeUInt; out Code: Integer); overload;
432
+ procedure val(const S: String; out SI : ShortInt; out Code: Integer); overload;
433
+ procedure val(const S: String; out B : Byte; out Code: Integer); overload;
434
+ procedure val(const S: String; out SI : smallint; out Code: Integer); overload;
435
+ procedure val(const S: String; out W : word; out Code : Integer); overload;
436
+ procedure val(const S: String; out I : integer; out Code : Integer); overload;
437
+ procedure val(const S: String; out C : Cardinal; out Code: Integer); overload;
438
+ procedure val(const S: String; out d : double; out Code : Integer); overload;
439
+ procedure val(const S: String; out b : boolean; out Code: Integer); overload;
440
+ function StringOfChar(c: Char; l: NativeInt): String;
441
+
442
+ {*****************************************************************************
443
+ Other functions
444
+ *****************************************************************************}
445
+ procedure Write; varargs; // ToDo: should be compiler built-in function
446
+ procedure Writeln; varargs; // ToDo: should be compiler built-in function
447
+
448
+ Type
449
+ TConsoleHandler = Reference to Procedure (S : JSValue; NewLine : Boolean);
450
+ Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
451
+
452
+ function Assigned(const V: JSValue): boolean; assembler; overload;
453
+ function StrictEqual(const A: JSValue; const B): boolean; assembler;
454
+ function StrictInequal(const A: JSValue; const B): boolean; assembler;
455
+
456
+ implementation
457
+
458
+ type
459
+
460
+ { TJSObj - simple access to JS Object }
461
+
462
+ TJSObj = class external name 'Object'
463
+ private
464
+ function GetProperties(Name: String): JSValue; external name '[]';
465
+ procedure SetProperties(Name: String; const AValue: JSValue); external name '[]';
466
+ public
467
+ //constructor new;
468
+ //function hasOwnProperty(prop: String): boolean;
469
+ property Properties[Name: String]: JSValue read GetProperties write SetProperties; default;
470
+ end;
471
+
472
+ TJSArray = class external name 'Array'
473
+ public
474
+ //length: nativeint;
475
+ //constructor new; overload;
476
+ function push(aElement : JSValue) : NativeInt; varargs;
477
+ end;
478
+
479
+ TJSArguments = class external name 'arguments'
480
+ private
481
+ FLength: NativeInt; external name 'length';
482
+ function GetElements(Index: NativeInt): JSValue; external name '[]';
483
+ public
484
+ property Length: NativeInt read FLength;
485
+ property Elements[Index: NativeInt]: JSValue read GetElements; default;
486
+ end;
487
+ var
488
+ JSArguments: TJSArguments; external name 'arguments';
489
+
490
+ function isNumber(const v: JSValue): boolean; external name 'rtl.isNumber';
491
+ function isObject(const v: JSValue): boolean; external name 'rtl.isObject'; // true if not null and a JS Object
492
+ function isString(const v: JSValue): boolean; external name 'rtl.isString';
493
+ function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
494
+
495
+ // needed by ClassNameIs, the real SameText is in SysUtils
496
+ function SameText(const s1, s2: String): Boolean; assembler;
497
+ asm
498
+ return s1.toLowerCase() == s2.toLowerCase();
499
+ end;
500
+
501
+ function VarRecs: TVarRecArray;
502
+ var
503
+ i: nativeint;
504
+ v: PVarRec;
505
+ begin
506
+ Result:=nil;
507
+ while i<JSArguments.Length do
508
+ begin
509
+ new(v);
510
+ v^.VType:=byte(JSArguments[i]);
511
+ inc(i);
512
+ v^.VJSValue:=JSArguments[i];
513
+ inc(i);
514
+ TJSArray(Result).push(v^);
515
+ end;
516
+ end;
517
+
518
+ function ParamCount: Longint;
519
+ begin
520
+ if Assigned(OnParamCount) then
521
+ Result:=OnParamCount()
522
+ else
523
+ Result:=0;
524
+ end;
525
+
526
+ function ParamStr(Index: Longint): String;
527
+ begin
528
+ if Assigned(OnParamStr) then
529
+ Result:=OnParamStr(Index)
530
+ else if Index=0 then
531
+ Result:='js'
532
+ else
533
+ Result:='';
534
+ end;
535
+
536
+ function Frac(const A: Double): Double; assembler;
537
+ asm
538
+ return A % 1;
539
+ end;
540
+
541
+ function Odd(const A: Integer): Boolean; assembler;
542
+ asm
543
+ return A&1 != 0;
544
+ end;
545
+
546
+ function Random(const Range: Integer): Integer; assembler;
547
+ asm
548
+ return Math.floor(Math.random()*Range);
549
+ end;
550
+
551
+ function Sqr(const A: Integer): Integer; assembler;
552
+ asm
553
+ return A*A;
554
+ end;
555
+
556
+ function Sqr(const A: Double): Double; assembler;
557
+ asm
558
+ return A*A;
559
+ end;
560
+
561
+ function Trunc(const A: Double): NativeInt; assembler;
562
+ asm
563
+ if (!Math.trunc) {
564
+ Math.trunc = function(v) {
565
+ v = +v;
566
+ if (!isFinite(v)) return v;
567
+ return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
568
+ };
569
+ }
570
+ $mod.Trunc = Math.trunc;
571
+ return Math.trunc(A);
572
+ end;
573
+
574
+ function Copy(const S: string; Index, Size: Integer): String; assembler;
575
+ asm
576
+ if (Index<1) Index = 1;
577
+ return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
578
+ end;
579
+
580
+ function Copy(const S: string; Index: Integer): String; assembler;
581
+ asm
582
+ if (Index<1) Index = 1;
583
+ return S.substr(Index-1);
584
+ end;
585
+
586
+ procedure Delete(var S: String; Index, Size: Integer);
587
+ var
588
+ h: String;
589
+ begin
590
+ if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
591
+ h:=S;
592
+ S:=copy(h,1,Index-1)+copy(h,Index+Size);
593
+ end;
594
+
595
+ function Pos(const Search, InString: String): Integer; assembler;
596
+ asm
597
+ return InString.indexOf(Search)+1;
598
+ end;
599
+
600
+ function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
601
+ asm
602
+ return InString.indexOf(Search,StartAt-1)+1;
603
+ end;
604
+
605
+ procedure Insert(const Insertion: String; var Target: String; Index: Integer);
606
+ var
607
+ t: String;
608
+ begin
609
+ if Insertion='' then exit;
610
+ t:=Target;
611
+ if Index<1 then
612
+ Target:=Insertion+t
613
+ else if Index>length(t) then
614
+ Target:=t+Insertion
615
+ else
616
+ Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
617
+ end;
618
+
619
+ var
620
+ WriteBuf: String;
621
+ WriteCallBack : TConsoleHandler;
622
+
623
+ Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
624
+
625
+ begin
626
+ Result:=WriteCallBack;
627
+ WriteCallBack:=H;
628
+ end;
629
+
630
+ procedure Write;
631
+ var
632
+ i: Integer;
633
+ begin
634
+ for i:=0 to JSArguments.Length-1 do
635
+ if Assigned(WriteCallBack) then
636
+ WriteCallBack(JSArguments[i],False)
637
+ else
638
+ WriteBuf:=WriteBuf+String(JSArguments[i]);
639
+ end;
640
+
641
+ procedure Writeln;
642
+
643
+ var
644
+ i,l: Integer;
645
+ s: String;
646
+
647
+ begin
648
+ L:=JSArguments.Length-1;
649
+ if Assigned(WriteCallBack) then
650
+ begin
651
+ for i:=0 to L do
652
+ WriteCallBack(JSArguments[i],I=L);
653
+ end
654
+ else
655
+ begin
656
+ s:=WriteBuf;
657
+ for i:=0 to L do
658
+ s:=s+String(JSArguments[i]);
659
+ asm
660
+ console.log(s);
661
+ end;
662
+ WriteBuf:='';
663
+ end;
664
+ end;
665
+
666
+ function Int(const A: Double): double;
667
+
668
+ begin
669
+ // trunc contains fix for missing Math.trunc in IE
670
+ Result:=Trunc(A);
671
+ end;
672
+
673
+ function Number(S: String): Double; external name 'Number';
674
+
675
+ function valint(const S: String; MinVal, MaxVal: NativeInt; out Code: Integer): NativeInt;
676
+ var
677
+ x: double;
678
+ begin
679
+ if S='' then
680
+ begin
681
+ code:=1;
682
+ exit;
683
+ end;
684
+ x:=Number(S);
685
+ if isNaN(x) then
686
+ case copy(s,1,1) of
687
+ '$': x:=Number('0x'+copy(S,2));
688
+ '&': x:=Number('0o'+copy(S,2));
689
+ '%': x:=Number('0b'+copy(S,2));
690
+ else
691
+ Code:=1;
692
+ exit;
693
+ end;
694
+ if isNaN(x) or (X<>Int(X)) then
695
+ Code:=1
696
+ else if (x<MinVal) or (x>MaxVal) then
697
+ Code:=2
698
+ else
699
+ begin
700
+ Result:=Trunc(x);
701
+ Code:=0;
702
+ end;
703
+ end;
704
+
705
+ procedure val(const S: String; out NI : NativeInt; out Code: Integer);
706
+ begin
707
+ NI:=valint(S,low(NI),high(NI),Code);
708
+ end;
709
+
710
+ procedure val(const S: String; out NI: NativeUInt; out Code: Integer);
711
+ var
712
+ x : double;
713
+ begin
714
+ if S='' then
715
+ begin
716
+ code:=1;
717
+ exit;
718
+ end;
719
+ x:=Number(S);
720
+ if isNaN(x) or (X<>Int(X)) or (X<0) then
721
+ Code:=1
722
+ else
723
+ begin
724
+ Code:=0;
725
+ NI:=Trunc(x);
726
+ end;
727
+ end;
728
+
729
+ procedure val(const S: String; out SI : ShortInt; out Code: Integer);
730
+ begin
731
+ SI:=valint(S,low(SI),high(SI),Code);
732
+ end;
733
+
734
+ procedure val(const S: String; out SI: smallint; out Code: Integer);
735
+ begin
736
+ SI:=valint(S,low(SI),high(SI),Code);
737
+ end;
738
+
739
+ procedure val(const S: String; out C: Cardinal; out Code: Integer);
740
+ begin
741
+ C:=valint(S,low(C),high(C),Code);
742
+ end;
743
+
744
+ procedure val(const S: String; out B: Byte; out Code: Integer);
745
+ begin
746
+ B:=valint(S,low(B),high(B),Code);
747
+ end;
748
+
749
+ procedure val(const S: String; out W: word; out Code: Integer);
750
+ begin
751
+ W:=valint(S,low(W),high(W),Code);
752
+ end;
753
+
754
+ procedure val(const S : String; out I : integer; out Code : Integer);
755
+ begin
756
+ I:=valint(S,low(I),high(I),Code);
757
+ end;
758
+
759
+ procedure val(const S : String; out d : double; out Code : Integer);
760
+ Var
761
+ x: double;
762
+ begin
763
+ if S='' then
764
+ begin
765
+ code:=1;
766
+ exit;
767
+ end;
768
+ x:=Number(S);
769
+ if isNaN(x) then
770
+ Code:=1
771
+ else
772
+ begin
773
+ Code:=0;
774
+ d:=x;
775
+ end;
776
+ end;
777
+
778
+ procedure val(const S: String; out b: boolean; out Code: Integer);
779
+ begin
780
+ if SameText(S,'true') then
781
+ begin
782
+ Code:=0;
783
+ b:=true;
784
+ end
785
+ else if SameText(S,'false') then
786
+ begin
787
+ Code:=0;
788
+ b:=false;
789
+ end
790
+ else
791
+ Code:=1;
792
+ end;
793
+
794
+ function binstr(val : NativeUInt;cnt : byte) : string;
795
+ var
796
+ i : Integer;
797
+ begin
798
+ SetLength(Result,cnt);
799
+ for i:=cnt downto 1 do
800
+ begin
801
+ Result[i]:=char(48+val and 1);
802
+ val:=val shr 1;
803
+ end;
804
+ end;
805
+
806
+ function upcase(c : char) : char; assembler;
807
+ asm
808
+ return c.toUpperCase();
809
+ end;
810
+
811
+ function StringOfChar(c: Char; l: NativeInt): String;
812
+ var
813
+ i: Integer;
814
+ begin
815
+ asm
816
+ if ((l>0) && c.repeat) return c.repeat(l);
817
+ end;
818
+ Result:='';
819
+ for i:=1 to l do Result:=Result+c;
820
+ end;
821
+
822
+ function Assigned(const V: JSValue): boolean; assembler;
823
+ asm
824
+ return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
825
+ end;
826
+
827
+ function StrictEqual(const A: JSValue; const B): boolean; assembler;
828
+ asm
829
+ return A === B;
830
+ end;
831
+
832
+ function StrictInequal(const A: JSValue; const B): boolean; assembler;
833
+ asm
834
+ return A !== B;
835
+ end;
836
+
837
+ { TContainedObject }
838
+
839
+ function TContainedObject.QueryInterface(const iid: TGuid; out obj): Integer;
840
+ begin
841
+ if GetInterface(iid,obj) then
842
+ Result:=S_OK
843
+ else
844
+ Result:=Integer(E_NOINTERFACE);
845
+ end;
846
+
847
+ { TAggregatedObject }
848
+
849
+ function TAggregatedObject.GetController: IUnknown;
850
+ begin
851
+ Result := IUnknown(fController);
852
+ end;
853
+
854
+ function TAggregatedObject.QueryInterface(const iid: TGuid; out obj): Integer;
855
+ begin
856
+ Result := IUnknown(fController).QueryInterface(iid, obj);
857
+ end;
858
+
859
+ function TAggregatedObject._AddRef: Integer;
860
+ begin
861
+ Result := IUnknown(fController)._AddRef;
862
+ end;
863
+
864
+ function TAggregatedObject._Release: Integer;
865
+ begin
866
+ Result := IUnknown(fController)._Release;
867
+ end;
868
+
869
+ constructor TAggregatedObject.Create(const aController: IUnknown);
870
+ begin
871
+ inherited Create;
872
+ { do not keep a counted reference to the controller! }
873
+ fController := Pointer(aController);
874
+ end;
875
+
876
+ { TInterfacedObject }
877
+
878
+ function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;
879
+ begin
880
+ if GetInterface(iid,obj) then
881
+ Result:=S_OK
882
+ else
883
+ Result:=Integer(E_NOINTERFACE);
884
+ end;
885
+
886
+ function TInterfacedObject._AddRef: Integer;
887
+ begin
888
+ inc(fRefCount);
889
+ Result:=fRefCount;
890
+ end;
891
+
892
+ function TInterfacedObject._Release: Integer;
893
+ begin
894
+ dec(fRefCount);
895
+ Result:=fRefCount;
896
+ if fRefCount=0 then
897
+ Destroy;
898
+ end;
899
+
900
+ procedure TInterfacedObject.BeforeDestruction;
901
+ begin
902
+ if fRefCount<>0 then
903
+ asm
904
+ rtl.raiseE('EHeapMemoryError');
905
+ end;
906
+ end;
907
+
908
+ { TObject }
909
+
910
+ constructor TObject.Create;
911
+ begin
912
+
913
+ end;
914
+
915
+ destructor TObject.Destroy;
916
+ begin
917
+
918
+ end;
919
+
920
+ procedure TObject.Free;
921
+ begin
922
+ Destroy;
923
+ end;
924
+
925
+ class function TObject.ClassType: TClass; assembler;
926
+ asm
927
+ return this;
928
+ end;
929
+
930
+ class function TObject.ClassNameIs(const Name: string): boolean;
931
+ begin
932
+ Result:=SameText(Name,ClassName);
933
+ end;
934
+
935
+ class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
936
+ asm
937
+ return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
938
+ end;
939
+
940
+ Class function TObject.MethodName(aCode : Pointer) : String;
941
+
942
+ begin
943
+ Result:='';
944
+ if aCode=Nil then
945
+ exit;
946
+ asm
947
+ if (typeof(aCode)!=='function') return "";
948
+ var i = 0;
949
+ var TI = this.$rtti;
950
+ if (rtl.isObject(aCode.scope)){
951
+ // callback
952
+ if (typeof aCode.fn === "string") return aCode.fn;
953
+ aCode = aCode.fn;
954
+ }
955
+ // Not a callback, check rtti
956
+ while ((Result === "") && (TI != null)) {
957
+ i = 0;
958
+ while ((Result === "") && (i < TI.methods.length)) {
959
+ if (this[TI.getMethod(i).name] === aCode)
960
+ Result=TI.getMethod(i).name;
961
+ i += 1;
962
+ };
963
+ if (Result === "") TI = TI.ancestor;
964
+ };
965
+ // return Result;
966
+ end;
967
+ end;
968
+
969
+ Class function TObject.MethodAddress(aName : String) : Pointer;
970
+
971
+ // We must do this in asm, because the typinfo unit is not available.
972
+ begin
973
+ Result:=Nil;
974
+ if AName='' then
975
+ exit;
976
+ asm
977
+ var i = 0;
978
+ var TI = this.$rtti;
979
+ var N = "";
980
+ var MN = "";
981
+ N = aName.toLowerCase();
982
+ while ((MN === "") && (TI != null)) {
983
+ i = 0;
984
+ while ((MN === "") && (i < TI.methods.length)) {
985
+ if (TI.getMethod(i).name.toLowerCase() === N) MN = TI.getMethod(i).name;
986
+ i += 1;
987
+ };
988
+ if (MN === "") TI = TI.ancestor;
989
+ };
990
+ if (MN !== "") Result = this[MN];
991
+ // return Result;
992
+ end;
993
+ end;
994
+
995
+ class function TObject.FieldAddress(aName: String): Pointer;
996
+
997
+ begin
998
+ Result:=Nil;
999
+ if aName='' then exit;
1000
+ asm
1001
+ var aClass = this.$class;
1002
+ var ClassTI = null;
1003
+ var myName = aName.toLowerCase();
1004
+ var MemberTI = null;
1005
+ while (aClass !== null) {
1006
+ ClassTI = aClass.$rtti;
1007
+ for (var i = 0, $end2 = ClassTI.fields.length - 1; i <= $end2; i++) {
1008
+ MemberTI = ClassTI.getField(i);
1009
+ if (MemberTI.name.toLowerCase() === myName) {
1010
+ return MemberTI;
1011
+ };
1012
+ };
1013
+ aClass = aClass.$ancestor ? aClass.$ancestor : null;
1014
+ };
1015
+ end;
1016
+ end;
1017
+
1018
+ Class Function TObject.ClassInfo : Pointer;
1019
+
1020
+ begin
1021
+ // This works different from FPC/Delphi.
1022
+ // We get the actual type info.
1023
+ Result:=TypeInfo(Self);
1024
+ end;
1025
+
1026
+ procedure TObject.AfterConstruction;
1027
+ begin
1028
+
1029
+ end;
1030
+
1031
+ procedure TObject.BeforeDestruction;
1032
+ begin
1033
+
1034
+ end;
1035
+
1036
+ procedure TObject.Dispatch(var aMessage);
1037
+ // aMessage is a record with an integer field 'Msg'
1038
+ var
1039
+ aClass: TClass;
1040
+ Msg: TJSObj absolute aMessage;
1041
+ Id: jsvalue;
1042
+ begin
1043
+ if not isObject(Msg) then exit;
1044
+ Id:=Msg['Msg'];
1045
+ if not isNumber(Id) then exit;
1046
+ aClass:=ClassType;
1047
+ while aClass<>nil do
1048
+ begin
1049
+ asm
1050
+ var Handlers = aClass.$msgint;
1051
+ if (rtl.isObject(Handlers) && Handlers.hasOwnProperty(Id)){
1052
+ this[Handlers[Id]](aMessage);
1053
+ return;
1054
+ }
1055
+ end;
1056
+ aClass:=aClass.ClassParent;
1057
+ end;
1058
+ DefaultHandler(aMessage);
1059
+ end;
1060
+
1061
+ procedure TObject.DispatchStr(var aMessage);
1062
+ // aMessage is a record with a string field 'MsgStr'
1063
+ var
1064
+ aClass: TClass;
1065
+ Msg: TJSObj absolute aMessage;
1066
+ Id: jsvalue;
1067
+ begin
1068
+ if not isObject(Msg) then exit;
1069
+ Id:=Msg['MsgStr'];
1070
+ if not isString(Id) then exit;
1071
+ aClass:=ClassType;
1072
+ while (aClass<>Nil) do
1073
+ begin
1074
+ asm
1075
+ var Handlers = aClass.$msgstr;
1076
+ if (rtl.isObject(Handlers) && Handlers.hasOwnProperty(Id)){
1077
+ this[Handlers[Id]](aMessage);
1078
+ return;
1079
+ }
1080
+ end;
1081
+ aClass:=aClass.ClassParent;
1082
+ end;
1083
+ DefaultHandlerStr(aMessage);
1084
+ end;
1085
+
1086
+ procedure TObject.DefaultHandler(var aMessage);
1087
+ begin
1088
+ if jsvalue(TMethod(aMessage)) then ;
1089
+ end;
1090
+
1091
+ procedure TObject.DefaultHandlerStr(var aMessage);
1092
+ begin
1093
+ if jsvalue(TMethod(aMessage)) then ;
1094
+ end;
1095
+
1096
+ function TObject.GetInterface(const iid: TGuid; out obj): boolean;
1097
+ begin
1098
+ asm
1099
+ var i = iid.$intf;
1100
+ if (i){
1101
+ // iid is the private TGuid of an interface
1102
+ i = rtl.getIntfG(this,i.$guid,2);
1103
+ if (i){
1104
+ obj.set(i);
1105
+ return true;
1106
+ }
1107
+ }
1108
+ end;
1109
+ Result := GetInterfaceByStr(GUIDToString(iid),obj);
1110
+ end;
1111
+
1112
+ function TObject.GetInterface(const iidstr: String; out obj): boolean;
1113
+ begin
1114
+ Result := GetInterfaceByStr(iidstr,obj);
1115
+ end;
1116
+
1117
+ function TObject.GetInterfaceByStr(const iidstr: String; out obj): boolean;
1118
+ begin
1119
+ Result:=false;
1120
+ if not TJSObj(IObjectInstance)['$str'] then
1121
+ TJSObj(IObjectInstance)['$str']:=GUIDToString(IObjectInstance);
1122
+ if iidstr = TJSObj(IObjectInstance)['$str'] then
1123
+ begin
1124
+ obj:=Self;
1125
+ exit(true);
1126
+ end;
1127
+ asm
1128
+ var i = rtl.getIntfG(this,iidstr,2);
1129
+ obj.set(i);
1130
+ Result=(i!==null);
1131
+ end;
1132
+ end;
1133
+
1134
+ function TObject.GetInterfaceWeak(const iid: TGuid; out obj): boolean;
1135
+ begin
1136
+ Result:=GetInterface(iid,obj);
1137
+ asm
1138
+ if (Result){
1139
+ var o = obj.get();
1140
+ if (o.$kind==='com'){
1141
+ o._Release();
1142
+ }
1143
+ }
1144
+ end;
1145
+ end;
1146
+
1147
+ function TObject.Equals(Obj: TObject): boolean;
1148
+ begin
1149
+ Result:=Obj=Self;
1150
+ end;
1151
+
1152
+ function TObject.ToString: String;
1153
+ begin
1154
+ Result:=ClassName;
1155
+ end;
1156
+
1157
+ class function TObject.QualifiedClassName: String;
1158
+ begin
1159
+ Result := UnitName + '.' + ClassName;
1160
+ end;
1161
+
1162
+ initialization
1163
+ ExitCode:=0; // set it here, so that WPO does not remove it
1164
+
1165
+ end.
1166
+