Browse Source

* PChar -> PAnsiChar

Michael VAN CANNEYT 2 years ago
parent
commit
f1680f05b6

+ 16 - 16
packages/fcl-js/src/jsminifier.pp

@@ -62,26 +62,26 @@ Type
 
   TJSONMinifier = Class(TComponent)
   Private
-    FA : char;
-    FB : char;
+    FA : AnsiChar;
+    FB : AnsiChar;
     FFileHeader: TStrings;
-    FLookahead : char;
-    FX : char;
-    FY : char ;
+    FLookahead : AnsiChar;
+    FX : AnsiChar;
+    FY : AnsiChar ;
     Fin : TStream;
     Fout : TStream;
     procedure SetFileHeader(AValue: TStrings);
   Protected
     // Token reading routines
-    function Peek : char;
-    function Get : char;inline;
-    function Next : char;
+    function Peek : AnsiChar;
+    function Get : AnsiChar;inline;
+    function Next : AnsiChar;
     // Token writing routines
-    procedure Putc(c: char);inline;
+    procedure Putc(c: AnsiChar);inline;
     Procedure Reset;
     procedure DoHeader; virtual;
     procedure Error(Const Msg: string);
-    Class Function isAlphaNum(c: char): boolean;
+    Class Function isAlphaNum(c: AnsiChar): boolean;
     Class Function iif(B : Boolean; Const ifTrue,ifFalse : integer) : integer; inline;
     procedure Action(d: Byte);
     procedure Minify;
@@ -136,14 +136,14 @@ begin
   FY:=EOS;
 end;
 
-class function TJSONMinifier.isAlphaNum(c: char): boolean;
+class function TJSONMinifier.isAlphaNum(c: AnsiChar): boolean;
 
 begin
   Result:= (C in ['a'..'z']) or (c in ['0'..'9']) or (c in ['A'..'Z']) or (C in ['_','$','\']) or (c > #126);
 end;
 
 
-function TJSONMinifier.Get: char;
+function TJSONMinifier.Get: AnsiChar;
 
 begin
   Result:=FLookahead;
@@ -159,16 +159,16 @@ begin
 end;
 
 
-function TJSONMinifier.Peek: char;
+function TJSONMinifier.Peek: AnsiChar;
 begin
   FLookahead := get();
   result:=FLookahead;
 end;
 
-function TJSONMinifier.Next: char;
+function TJSONMinifier.Next: AnsiChar;
 
 var
- c : char;
+ c : AnsiChar;
 
 begin
   c:= get();
@@ -200,7 +200,7 @@ begin
   Result:=c;
 end;
 
-procedure TJSONMinifier.Putc(c: char);
+procedure TJSONMinifier.Putc(c: AnsiChar);
 
 begin
   Fout.writebuffer(c,sizeof(c));

+ 37 - 36
packages/fcl-js/src/jsscanner.pp

@@ -47,16 +47,17 @@ resourcestring
   SErrInvalidRegularExpression = 'Syntax error in regular expression: / expected, got: %s';
 
 Type
+  TJSScannerString = UTF8String;
 
   { TLineReader }
 
   TLineReader = class
   private
-    FLastLF: string;
+    FLastLF: TJSScannerString;
   public
     function IsEOF: Boolean; virtual; abstract;
-    function ReadLine: string; virtual; abstract;
-    Property LastLF : string Read FLastLF Write FLastLF;
+    function ReadLine: TJSScannerString; virtual; abstract;
+    Property LastLF : TJSScannerString Read FLastLF Write FLastLF;
   end;
 
   { TStreamLineReader }
@@ -71,7 +72,7 @@ Type
   public
     Constructor Create(AStream : TStream);
     function IsEOF: Boolean; override;
-    function ReadLine: string; override;
+    function ReadLine: TJSScannerString; override;
   end;
 
   TFileLineReader = class(TLineReader)
@@ -79,10 +80,10 @@ Type
     FTextFile: Text;
     FileOpened: Boolean;
   public
-    constructor Create(const AFilename: string);
+    constructor Create(const AFilename: TJSScannerString);
     destructor Destroy; override;
     function IsEOF: Boolean; override;
-    function ReadLine: string; override;
+    function ReadLine: TJSScannerString; override;
   end;
 
   EJSScannerError       = class(Exception);
@@ -97,13 +98,13 @@ Type
     FReturnComments: Boolean;
     FReturnWhiteSpace: Boolean;
     FSourceFile: TLineReader;
-    FSourceFilename: string;
+    FSourceFilename: String;
     FCurRow: Integer;
     FCurToken: TJSToken;
-    FCurTokenString: UTF8String;
-    FCurLine: string;
+    FCurTokenString: TJSScannerString;
+    FCurLine: TJSScannerString;
     FWasMultilineString: Boolean;
-    TokenStr: PChar;
+    TokenStr: PAnsiChar;
     FWasEndOfLine : Boolean;
     FSourceStream : TStream;
     FOwnSourceFile : Boolean;
@@ -122,13 +123,13 @@ Type
     procedure SetECMAVersion(AValue: TECMAVersion);
     procedure SetIsTypeScript(AValue: Boolean);
   protected
-    procedure Error(const Msg: string);overload;
-    procedure Error(const Msg: string; Args: array of Const);overload;
+    procedure Error(const Msg: TJSScannerString);overload;
+    procedure Error(const Msg: TJSScannerString; Args: array of Const);overload;
   public
     constructor Create(ALineReader: TLineReader; aECMAVersion : TECMAVersion = ecma5);
-    constructor Create(AStream : TStream; aECMAVersion : TECMAVersion = ecma5; const aFileName : string = '');
+    constructor Create(AStream : TStream; aECMAVersion : TECMAVersion = ecma5; const aFileName : TJSScannerString = '');
     destructor Destroy; override;
-    procedure OpenFile(const AFilename: string);
+    procedure OpenFile(const AFilename: TJSScannerString);
     Function FetchRegexprToken: TJSToken;
     Function FetchToken: TJSToken;
     Function IsEndOfLine : Boolean;
@@ -136,8 +137,8 @@ Type
     Property ReturnComments : Boolean Read FReturnComments Write FReturnComments;
     Property ReturnWhiteSpace : Boolean Read FReturnWhiteSpace Write FReturnWhiteSpace;
     property SourceFile: TLineReader read FSourceFile;
-    property CurFilename: string read FSourceFilename;
-    property CurLine: string read FCurLine;
+    property CurFilename: String read FSourceFilename;
+    property CurLine: TJSScannerString read FCurLine;
     property CurRow: Integer read FCurRow;
     property CurColumn: Integer read GetCurColumn;
     property CurToken: TJSToken read FCurToken;
@@ -152,7 +153,7 @@ Type
 implementation
 
 
-constructor TFileLineReader.Create(const AFilename: string);
+constructor TFileLineReader.Create(const AFilename: TJSScannerString);
 begin
   inherited Create;
   Assign(FTextFile, AFilename);
@@ -172,7 +173,7 @@ begin
   Result := EOF(FTextFile);
 end;
 
-function TFileLineReader.ReadLine: string;
+function TFileLineReader.ReadLine: TJSScannerString;
 begin
   ReadLn(FTextFile, Result);
 end;
@@ -185,7 +186,7 @@ begin
   FNonKeyWords:=NonJSKeywords[aECMAVersion];
 end;
 
-constructor TJSScanner.Create(AStream: TStream; aECMAVersion: TECMAVersion; Const aFileName : string = '');
+constructor TJSScanner.Create(AStream: TStream; aECMAVersion: TECMAVersion; Const aFileName : TJSScannerString = '');
 begin
   FSourceStream:=ASTream;
   FOwnSourceFile:=True;
@@ -200,7 +201,7 @@ begin
   inherited Destroy;
 end;
 
-procedure TJSScanner.OpenFile(const AFilename: string);
+procedure TJSScanner.OpenFile(const AFilename: TJSScannerString);
 begin
   FSourceFile := TFileLineReader.Create(AFilename);
   FSourceFilename := AFilename;
@@ -215,12 +216,12 @@ begin
 end;
 
 
-procedure TJSScanner.Error(const Msg: string);
+procedure TJSScanner.Error(const Msg: TJSScannerString);
 begin
   raise EJSScannerError.Create(Msg);
 end;
 
-procedure TJSScanner.Error(const Msg: string; Args: array of Const);
+procedure TJSScanner.Error(const Msg: TJSScannerString; Args: array of Const);
 begin
   raise EJSScannerError.CreateFmt(Msg, Args);
 end;
@@ -235,7 +236,7 @@ begin
   end else
   begin
     FCurLine := FSourceFile.ReadLine;
-    TokenStr := PChar(CurLine);
+    TokenStr := PAnsiChar(CurLine);
     Result := true;
     Inc(FCurRow);
     FWasEndofLine:=True;
@@ -260,7 +261,7 @@ end;
 function TJSScanner.DoSingleLineComment : TJSToken;
 
 Var
-  TokenStart : PChar;
+  TokenStart : PAnsiChar;
   Len : Integer;
 
 begin
@@ -278,9 +279,9 @@ end;
 function TJSScanner.DoMultiLineComment : TJSToken;
 
 Var
-  TokenStart : PChar;
+  TokenStart : PAnsiChar;
   Len,OLen : Integer;
-  PrevToken : Char;
+  PrevToken : AnsiChar;
 
 begin
   Inc(TokenStr);
@@ -342,7 +343,7 @@ end;
 function TJSScanner.ReadUnicodeEscape: WideChar;
 
 Var
-  S : String;
+  S : TJSScannerString;
   I : Integer;
 
 begin
@@ -367,7 +368,7 @@ Var
   CC : Boolean; // Character class
   Done : Boolean;
   CL,L : Integer;
-  TokenStart : PChar;
+  TokenStart : PAnsiChar;
 
 begin
   if (CurToken<>tjsDivEq) then
@@ -423,8 +424,8 @@ end;
 function TJSScanner.DoStringLiteral: TJSToken;
 
 Var
-  Delim : Char;
-  TokenStart : PChar;
+  Delim : AnsiChar;
+  TokenStart : PAnsiChar;
   Len,OLen: Integer;
   S : UTF8String;
 
@@ -474,7 +475,7 @@ begin
         Move(TokenStart^, FCurTokenString[OLen + 1], Len);
       Move(S[1],FCurTokenString[OLen + Len+1],Length(S));
       Inc(OLen, Len+Length(S));
-      // Next char
+      // Next AnsiChar
       // Inc(TokenStr);
       TokenStart := TokenStr+1;
       end;
@@ -504,7 +505,7 @@ end;
 function TJSScanner.DoNumericLiteral :TJSToken;
 
 Var
-  TokenStart : PChar;
+  TokenStart : PAnsiChar;
   Len : Integer;
 
 begin
@@ -558,7 +559,7 @@ end;
 function TJSScanner.DoIdentifier : TJSToken;
 
 Var
-  TokenStart:PChar;
+  TokenStart:PAnsiChar;
   Len : Integer;
   I : TJSToken;
 
@@ -921,7 +922,7 @@ end;
 
 function TJSScanner.GetCurColumn: Integer;
 begin
-  Result := TokenStr - PChar(CurLine);
+  Result := TokenStr - PAnsiChar(CurLine);
 end;
 
 { TStreamLineReader }
@@ -951,7 +952,7 @@ begin
   FBufPos:=0;
 end;
 
-function TStreamLineReader.ReadLine: string;
+function TStreamLineReader.ReadLine: TJSScannerString;
 
 Var
   FPos,OLen,Len: Integer;
@@ -989,7 +990,7 @@ begin
     end;
   If (PRun^ in [10,13]) and (FBufPos<FBufLen) then
     begin
-    LastLF:=PChar(PRun)^;
+    LastLF:=PAnsiChar(PRun)^;
     Inc(FBufPos);
     // Check #13#10
     If (PRun^=13) then

+ 33 - 26
packages/fcl-js/src/jssrcmap.pas

@@ -50,7 +50,7 @@ uses
   ;
 
 const
-  Base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+  Base64Chars = AnsiString('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');
 
 type
   EJSSourceMap = class(Exception);
@@ -136,8 +136,8 @@ type
       SrcLine: integer = 1; // 1-based
       SrcCol: integer = 0; // 0-based
       const Name: String = ''): TSourceMapSegment; virtual;
-    function CreateMappings: String; virtual;
-    procedure ParseMappings(const Mapping: String); virtual;
+    function CreateMappings: AnsiString; virtual;
+    procedure ParseMappings(const Mapping: AnsiString); virtual;
     function ToJSON: TJSONObject; virtual;
     function ToString: string; override;
     procedure LoadFromJSON(Obj: TJSONObject); virtual;
@@ -168,10 +168,10 @@ type
 
 function DefaultSrcMapHeader: string;
 
-function EncodeBase64VLQ(i: NativeInt): String; // base64 Variable Length Quantity
-function DecodeBase64VLQ(const s: string): NativeInt; // base64 Variable Length Quantity
+function EncodeBase64VLQ(i: NativeInt): AnsiString; // base64 Variable Length Quantity
+function DecodeBase64VLQ(const s: Ansistring): NativeInt; // base64 Variable Length Quantity
 function DecodeBase64VLQ(
-  {$ifdef UsePChar}var p: PChar{$else}const s: string; var p: integer{$endif}): NativeInt; // base64 Variable Length Quantity
+  {$ifdef UsePChar}var p: PAnsiChar{$else}const s: string; var p: integer{$endif}): NativeInt; // base64 Variable Length Quantity
 
 function CompareSegmentWithGeneratedLineCol(
   Item1, Item2: {$ifdef pas2js}jsvalue{$else}Pointer{$endif}): Integer;
@@ -186,7 +186,7 @@ begin
   Result:=')]}'''+LineEnding;
 end;
 
-function EncodeBase64VLQ(i: NativeInt): String;
+function EncodeBase64VLQ(i: NativeInt): AnsiString;
 { Convert signed number to base64-VLQ:
   Each base64 has 6bit, where the most significant bit is the continuation bit
   (1=there is a next base64 character).
@@ -225,15 +225,15 @@ begin
     digits:=i and %11111;
     i:=i shr 5;
     if i>0 then
-      inc(digits,%100000); // need another char -> set continuation bit
+      inc(digits,%100000); // need another AnsiChar -> set continuation bit
     Result:=Result+Base64Chars[digits+1];
   until i=0;
 end;
 
-function DecodeBase64VLQ(const s: string): NativeInt;
+function DecodeBase64VLQ(const s: Ansistring): NativeInt;
 var
   {$ifdef UsePChar}
-  p: PChar;
+  p,pend: PAnsiChar;
   {$else}
   p: integer;
   {$endif}
@@ -241,9 +241,11 @@ begin
   if s='' then
     raise EConvertError.Create('DecodeBase64VLQ empty');
   {$ifdef UsePChar}
-  p:=PChar(s);
+  p:=PAnsiChar(s);
+  pend:=p;
+  inc(pend,length(s));
   Result:=DecodeBase64VLQ(p);
-  if p-PChar(s)<>length(s) then
+  if p<>pend then
     raise EConvertError.Create('DecodeBase64VLQ waste');
   {$else}
   p:=1;
@@ -252,13 +254,13 @@ begin
 end;
 
 function DecodeBase64VLQ(
-  {$ifdef UsePChar}var p: PChar{$else}const s: string; var p: integer{$endif}): NativeInt;
+  {$ifdef UsePChar}var p: PAnsiChar{$else}const s: string; var p: integer{$endif}): NativeInt;
 { Convert base64-VLQ to signed number,
   For the fomat see EncodeBase64VLQ
 }
 var
   {$ifdef UsePChar}
-  run: PChar;
+  run: PAnsiChar;
   {$else}
   run, l: integer;
   {$endif}
@@ -296,7 +298,8 @@ begin
     '0'..'9': digit:=ord(c)-ord('0')+52;
     '+': digit:=62;
     '/': digit:=63;
-    else RaiseInvalid;
+    else
+      RaiseInvalid;
     end;
     inc(run);
     if Shift>MaxShift then
@@ -679,7 +682,7 @@ begin
   FItems.Add(Result);
 end;
 
-function TSourceMap.CreateMappings: String;
+function TSourceMap.CreateMappings: AnsiString;
 
 {$ifdef pas2js}
 var
@@ -690,7 +693,7 @@ var
     buf.push(s);
   end;
 
-  procedure AddChar(c: char); inline;
+  procedure AddChar(c: Char); inline;
   begin
     buf.push(c);
   end;
@@ -698,15 +701,15 @@ var
 var
   buf: TMemoryStream;
 
-  procedure AddStr(const s: string);
+  procedure AddStr(const s: Ansistring);
   begin
     if s<>'' then
-      buf.Write(s[1],length(s)*sizeof(char));
+      buf.Write(s[1],length(s)*sizeof(AnsiChar));
   end;
 
-  procedure AddChar({%H-}c: char);
+  procedure AddChar({%H-}c: AnsiChar);
   begin
-    buf.Write(c,sizeof(char));
+    buf.Write(c,sizeof(AnsiChar));
   end;
 {$endif}
 
@@ -803,12 +806,12 @@ begin
   end;
 end;
 
-procedure TSourceMap.ParseMappings(const Mapping: String);
+procedure TSourceMap.ParseMappings(const Mapping: AnsiString);
 const
   MaxInt = High(integer) div 2;
 {$ifdef UsePChar}
 var
-  p: PChar;
+  p,pend: PAnsiChar;
 
   function Decode: NativeInt; inline;
   begin
@@ -817,7 +820,7 @@ var
 
   procedure E(const Msg: string);
   begin
-    raise EJSSourceMap.CreateFmt(Msg,[PtrUInt(p-PChar(Mapping))+1]);
+    raise EJSSourceMap.CreateFmt(Msg,[PtrUInt(p-PAnsiChar(Mapping))+1]);
   end;
 {$else}
 var
@@ -843,7 +846,11 @@ var
 begin
   l:=length(Mapping);
   if l=0 then exit;
-  p:={$ifdef UsePChar}PChar(Mapping){$else}1{$endif};
+  p:={$ifdef UsePChar}PAnsiChar(Mapping){$else}1{$endif};
+  {$ifdef UsePChar}
+  pend:=PAnsiChar(Mapping);
+  Inc(pend,l);
+  {$endif}
   GeneratedLine:=1;
   LastColumn:=0;
   LastSrcFileIndex:=0;
@@ -855,7 +862,7 @@ begin
     case {$ifdef UsePChar}p^{$else}Mapping[p]{$endif} of
     {$ifdef UsePChar}
     #0:
-      if p-PChar(Mapping)=length(Mapping) then
+      if p>=pend then
         exit
       else
         E('unexpected #0 at %d');

+ 1 - 1
packages/fcl-js/src/jstoken.pp

@@ -60,7 +60,7 @@ const
 
   TokenInfos: array[TJSToken] of String = ('unknown',
        // Specials
-        'EOF','whitespace','Char','String', 'identifier','number','comment','regular expression', 'reserved word',
+        'EOF','whitespace','AnsiChar','String', 'identifier','number','comment','regular expression', 'reserved word',
         '&&','&=',
         '(',')','[',']','{','}',
         ',',':','.',';','=','>','<','?',

+ 26 - 19
packages/fcl-js/src/jswriter.pp

@@ -66,7 +66,7 @@ Type
     Function Write(Const Args : Array of const) : Integer;
     Function WriteLn(Const Args : Array of const) : Integer;
     Property CurLine: integer read FCurLine write FCurLine;
-    Property CurColumn: integer read FCurColumn write FCurColumn;// char index, not codepoint
+    Property CurColumn: integer read FCurColumn write FCurColumn;// AnsiChar index, not codepoint
     Property CurElement: TJSElement read FCurElement write SetCurElement;
     Property OnWriting: TTextWriterWriting read FOnWriting write FOnWriting;
     Property LineBreak: string read FLineBreak write FLineBreak;
@@ -164,7 +164,7 @@ Type
   private
     FCurIndent : Integer;
     FFreeWriter : Boolean;
-    FIndentChar : Char;
+    FIndentChar : AnsiChar;
     FIndentSize: Byte;
     FLastChar: WideChar;
     FLinePos : Integer;
@@ -246,7 +246,7 @@ Type
   EJSWriter = Class(Exception);
 
 {$ifdef FPC_HAS_CPSTRING}
-Function UTF16ToUTF8(const S: UnicodeString): string;
+Function UTF16ToUTF8(const S: UnicodeString): ansistring;
 {$endif}
 Function QuoteJSString(const S: TJSString; Quote: TJSChar = #0): TJSString;
 
@@ -257,7 +257,7 @@ Resourcestring
   SErrNilNode = 'Nil node in Javascript';
 
 {$ifdef FPC_HAS_CPSTRING}
-function HexDump(p: PChar; Count: integer): string;
+function HexDump(p: PAnsiChar; Count: integer): string;
 var
   i: Integer;
 begin
@@ -266,7 +266,7 @@ begin
     Result:=Result+HexStr(ord(p[i]),2);
 end;
 
-function UTF16ToUTF8(const S: UnicodeString): string;
+function UTF16ToUTF8(const S: UnicodeString): ansistring;
 begin
   Result:=UTF8Encode(S);
   // prevent UTF8 codepage appear in the strings - we don't need codepage
@@ -501,7 +501,7 @@ end;
 procedure TJSWriter.Write(const U: UnicodeString);
 
 Var
-  S : String;
+  S : UTF8String;
 
 begin
   //system.writeln('TJSWriter.Write unicodestring=',U);
@@ -511,7 +511,7 @@ begin
     S:=UTF16ToUTF8(U);
     if S='' then exit;
     FLinePos:=FLinePos+Writer.Write(S);
-    FLastChar:=WideChar(S[length(S)]);
+    FLastChar:=AnsiChar(S[length(S)]);
     end
   else if U<>'' then
     begin
@@ -533,7 +533,7 @@ begin
     WriteIndent;
     if s='' then exit;
     FLinePos:=FLinePos+Writer.Write(S);
-    FLastChar:=WideChar(S[length(S)]);
+    FLastChar:=Char(S[length(S)]);
     end;
 end;
 
@@ -547,7 +547,7 @@ begin
     begin
     WriteIndent;
     Writer.WriteLn(S);
-    FLastChar:=WideChar(#10);
+    FLastChar:=Char(#10);
     FLinePos:=0;
     end;
 end;
@@ -555,7 +555,7 @@ end;
 {$ifdef FPC_HAS_CPSTRING}
 procedure TJSWriter.WriteLn(const U: UnicodeString);
 Var
-  S : String;
+  S : AnsiString;
 
 begin
   if UseUTF8 then
@@ -611,7 +611,7 @@ begin
             c:=S[I+1];
             if (c>=#$D000) and (c<=#$DFFF) then
               begin
-              inc(I,2); // surrogate, two char codepoint
+              inc(I,2); // surrogate, two AnsiChar codepoint
               continue;
               end;
             // invalid UTF-16, cannot be encoded as UTF-8 -> encode as hex
@@ -687,7 +687,7 @@ const
   end;
 
 Var
-  S , S2: String;
+  S , S2: TJSString;
   JS: TJSString;
   p, StartP: Integer;
   MinIndent, CurLineIndent, j, Exp, Code: Integer;
@@ -2190,18 +2190,20 @@ end;
 {$ifdef FPC_HAS_CPSTRING}
 function TTextWriter.Write(const S: UnicodeString): Integer;
 var
-  p: PWideChar;
+  p,pend: PWideChar;
   c: WideChar;
 begin
   if S='' then exit;
   Writing;
   Result:=DoWrite(S);
   p:=PWideChar(S);
+  pend:=p;
+  inc(PEnd,Length(S));
   repeat
     c:=p^;
     case c of
     #0:
-      if p-PWideChar(S)=length(S)*2 then
+      if p>=pend then
         break
       else
         inc(FCurColumn);
@@ -2214,7 +2216,7 @@ begin
       continue;
       end;
     else
-      // ignore low/high surrogate, CurColumn is char index, not codepoint
+      // ignore low/high surrogate, CurColumn is AnsiChar index, not codepoint
       inc(FCurColumn);
     end;
     inc(p);
@@ -2224,7 +2226,7 @@ end;
 
 function TTextWriter.Write(const S: TJSWriterString): Integer;
 var
-  c: Char;
+  c: AnsiChar;
   l, p: Integer;
 begin
   if S='' then exit;
@@ -2244,7 +2246,7 @@ begin
       if (p<=l) and (S[p] in [#10,#13]) and (c<>S[p]) then inc(p);
       end;
     else
-      // Note about UTF-8 multibyte chars: CurColumn is char index, not codepoint
+      // Note about UTF-8 multibyte chars: CurColumn is AnsiChar index, not codepoint
       inc(FCurColumn);
       inc(p);
     end;
@@ -2253,7 +2255,12 @@ end;
 
 function TTextWriter.WriteLn(const S: TJSWriterString): Integer;
 begin
-  Result:=Write(S)+Write(LineBreak);
+  Result:=Write(S);
+{$IF SIZEOF(Char)=1}
+  Result:=Result+Write(LineBreak);
+{$else}
+  Result:=Result+Write(UTF8Encode(LineBreak));
+{$ENDIF}
 end;
 
 function TTextWriter.Write(const Fmt: TJSWriterString;
@@ -2313,7 +2320,7 @@ begin
        vtString        : S:=V.VString^;
        vtPChar         : S:=V.VPChar;
        vtPWideChar     : U:=V.VPWideChar;
-       vtAnsiString    : S:=PChar(V.VAnsiString);
+       vtAnsiString    : S:=PAnsiChar(V.VAnsiString);
        vtCurrency      : Str(V.VCurrency^,S);
        vtVariant       : S:=V.VVariant^;
        vtWideString    : U:=PWideChar(V.VWideString);

+ 9 - 7
packages/fcl-js/tests/tcscanner.pp

@@ -1,6 +1,8 @@
 unit tcscanner;
 
-{$mode objfpc}{$H+}
+{$mode objfpc}
+{$H+}
+{$codepage UTF8}
 
 interface
 
@@ -40,14 +42,14 @@ type
     FScanner : TJSScanner;
     FErrorSource : String;
     procedure AssertEquals(AMessage: String; AExpected, AActual : TJSToken); overload;
-    procedure CheckToken(AToken: TJSToken; ASource: String; aVersion : TECMAVersion = ecma5);
-    procedure CheckTokens(ASource: String; ATokens: array of TJSToken; aVersion : TECMAVersion = ecma5);
+    procedure CheckToken(AToken: TJSToken; ASource: TJSScannerString; aVersion : TECMAVersion = ecma5);
+    procedure CheckTokens(ASource: TJSScannerString; ATokens: array of TJSToken; aVersion : TECMAVersion = ecma5);
     procedure DoTestFloat(F: Double);
     procedure DoTestFloat(F: Double; S: String);
     procedure DoTestString(S: String; WasMultiline : Boolean = False);
     procedure TestErrorSource;
   protected
-    Function CreateScanner(AInput : String; aVersion : TECMAVersion = ecma5) : TJSScanner;
+    Function CreateScanner(AInput : TJSScannerString; aVersion : TECMAVersion = ecma5) : TJSScanner;
     procedure FreeScanner;
     procedure SetUp; override;
     procedure TearDown; override;
@@ -181,7 +183,7 @@ type
 
 implementation
 
-Function TTestJSScanner.CreateScanner(AInput : String; aVersion : TECMAVersion = ecma5) : TJSScanner;
+Function TTestJSScanner.CreateScanner(AInput : TJSScannerString; aVersion : TECMAVersion = ecma5) : TJSScanner;
 
 begin
   FStream:=TStringStream.Create(AInput);
@@ -235,7 +237,7 @@ begin
     end;
 end;
 
-procedure TTestJSScanner.CheckToken(AToken: TJSToken; ASource: String; aVersion: TECMAVersion);
+procedure TTestJSScanner.CheckToken(AToken: TJSToken; ASource: TJSScannerString; aVersion: TECMAVersion);
 
 Var
   J : TJSToken;
@@ -794,7 +796,7 @@ begin
   CheckToken(tjsYield,'yield',ecma2021);
 end;
 
-procedure TTestJSScanner.CheckTokens(ASource : String; ATokens : Array of TJSToken; aVersion: TECMAVersion = ecma5);
+procedure TTestJSScanner.CheckTokens(ASource : TJSScannerString; ATokens : Array of TJSToken; aVersion: TECMAVersion = ecma5);
 
 Var
   I : Integer;

+ 3 - 3
packages/fcl-js/tests/tcsrcmap.pas

@@ -48,14 +48,14 @@ end;
 procedure TTestSrcMap.Test_Base64VLQ;
 var
   i: Integer;
-  s: String;
-  p: PChar;
+  s: AnsiString;
+  p: PAnsiChar;
   j: NativeInt;
 begin
   for i:=-511 to 511 do
   begin
     s:=EncodeBase64VLQ(i);
-    p:=PChar(s);
+    p:=PAnsiChar(s);
     j:=DecodeBase64VLQ(p);
     if i<>j then
       Fail('Encode/DecodeBase64VLQ OrigIndex='+IntToStr(i)+' Code="'+s+'" NewIndex='+IntToStr(j));

+ 8 - 6
packages/fcl-js/tests/tcwriter.pp

@@ -1,6 +1,8 @@
 unit tcwriter;
 
-{$mode objfpc}{$H+}
+{$mode objfpc}
+{$H+}
+{$codepage utf8}
 
 interface
 
@@ -20,9 +22,9 @@ type
     procedure SetUp; override;
     procedure TearDown; override;
     Procedure WriteElement(JS : TJSElement); // Set element in Element, write. Freed on teardown
-    Procedure AssertResult(Const Msg, Result : String); // Compare result;
+    Procedure AssertResult(Const Msg, Result : AnsiString); // Compare result;
     Procedure AssertResult(Const Msg : string; Result : UnicodeString); // Compare result;
-    Procedure AssertWrite(Const Msg, Result : String; AElement : TJSElement); // Call writelement, compare result;
+    Procedure AssertWrite(Const Msg : String; Result : AnsiString; AElement : TJSElement); // Call writelement, compare result;
     Procedure AssertWrite(Const Msg : string; Result : UnicodeString; AElement : TJSElement); // Call writelement, compare result;
     Function CreateIdent(Const AName : String) : TJSPrimaryExpressionIdent;
     Function CreateLiteral(Const AValue : TJSString) : TJSLiteral;
@@ -3046,7 +3048,7 @@ begin
   FWriter.WriteJS(JS);
 end;
 
-Procedure TTestJSWriter.AssertResult(Const Msg, Result: String);
+Procedure TTestJSWriter.AssertResult(Const Msg, Result: AnsiString);
 
 Var
   S : AnsiString;
@@ -3070,7 +3072,7 @@ Var
   S : UnicodeString;
   p: Integer;
 begin
-  S:=FTextWriter.AsUnicodeString;
+  S:=UTF8Decode(FTextWriter.AsString);
   if S=Result then exit;
   p:=1;
   while (p<=length(S)) and (p<=length(Result)) and (S[p]=Result[p]) do inc(p);
@@ -3082,7 +3084,7 @@ begin
     AssertEquals(Msg+' (diff at '+IntToStr(p)+' "'+String(S[p])+'")',String(Result),String(S));
 end;
 
-Procedure TTestJSWriter.AssertWrite(Const Msg, Result: String;
+Procedure TTestJSWriter.AssertWrite(Const Msg : String; Result: AnsiString;
   AElement: TJSElement);
 begin
   WriteElement(AElement);

+ 14 - 14
packages/fcl-js/tests/testjs.lpi

@@ -19,23 +19,11 @@
       <Version Value="2"/>
     </PublishOptions>
     <RunParams>
-      <local>
-        <CommandLineParams Value="--suite=TTestTSToPas.TestObjectOneReadOnlyPropertyKeyword"/>
-      </local>
       <FormatVersion Value="2"/>
       <Modes Count="1">
-        <Mode0 Name="default">
-          <local>
-            <CommandLineParams Value="--suite=TTestTSToPas.TestObjectOneReadOnlyPropertyKeyword"/>
-          </local>
-        </Mode0>
+        <Mode0 Name="default"/>
       </Modes>
     </RunParams>
-    <RequiredPackages Count="1">
-      <Item1>
-        <PackageName Value="FCL"/>
-      </Item1>
-    </RequiredPackages>
     <Units Count="15">
       <Unit0>
         <Filename Value="testjs.lpr"/>
@@ -120,9 +108,12 @@
         <OptimizationLevel Value="0"/>
       </Optimizations>
     </CodeGeneration>
+    <Other>
+      <CustomOptions Value="-tunicodertl"/>
+    </Other>
   </CompilerOptions>
   <Debugging>
-    <Exceptions Count="3">
+    <Exceptions Count="6">
       <Item1>
         <Name Value="EAbort"/>
       </Item1>
@@ -132,6 +123,15 @@
       <Item3>
         <Name Value="EFOpenError"/>
       </Item3>
+      <Item4>
+        <Name Value="EAssertionFailedError"/>
+      </Item4>
+      <Item5>
+        <Name Value="EJSScannerError"/>
+      </Item5>
+      <Item6>
+        <Name Value="EJSParser"/>
+      </Item6>
     </Exceptions>
   </Debugging>
 </CONFIG>