2
0
Эх сурвалжийг харах

examples: added example for using libpas2js.dll and demonstrating unit alias

mattias 4 жил өмнө
parent
commit
633ffb57f9

+ 73 - 0
demo/uselibpas2js/Readme.txt

@@ -0,0 +1,73 @@
+Demo for using libpas2js.dll, the dynamic library of the pas2js compiler.
+
+If you use the release, libpas2js.dll is in the bin folder.
+
+If you use trunk and used 'make all' to build you got
+  bin\<targetos>-<targetcpu>\libpas2jslib.dll
+Copy that file and rename it to libpas2js.dll
+
+You can build libpas2js.dll directly by using Lazarus or lazbuild to compile
+  compiler/utils/pas2js/pas2jslib.lpi
+
+Anyway you should now have the library:
+libpas2js.so on Linux
+libpas2js.dynlib on macOS
+libpas2js.dll on Windows
+
+Now compile pas2js_unitalias.lpi
+This creates pas2js_unitalias or under Windows pas2js_unitalias.exe.
+
+It simply passes the command line parameters to run the compiler, so it behaves
+pretty much like the command line compiler pas2js.
+
+With one exception:
+pas2jscompilerproxy.pas Function DoUnitAlias redirects searching for some units:
+
+  if SameText(Old,'Test.Foo.Alias1') then
+    New:='Bar'
+  else if SameText(Old,'Test.Foo.Alias2') then
+    New:='Test.Foo.SomeLongUnitName';
+
+The example unit examples/TestUnitAlias1.pas uses "Test.Foo.Alias1".
+
+
+Open a console aka terminal, cd to this folder and invoke the compiler:
+
+Linux/Mac:
+./pas2js_unitalias -Jc -Tnodejs -Fu../../packages/rtl examples/TestUnitAlias1.pas -vt
+
+Windows:
+pas2js_unitalias.exe -Jc -Tnodejs -Fu..\..\packages\rtl examples\TestUnitAlias1.pas -vt
+
+You should see something like this:
+
+Log : Info: Configfile search: /home/mattias/.pas2js.cfg
+Log : Info: Configfile search: /home/mattias/pas2js/demo/uselibpas2js/pas2js.cfg
+Log : Info: Configfile search: /etc/pas2js.cfg
+Log : Info: Compiler exe: "/home/mattias/pas2js/demo/uselibpas2js/pas2js_unitalias"
+Log : Info: Using working directory: "/home/mattias/pas2js/demo/uselibpas2js"
+Log : Info: Using unit path: "/home/mattias/pas2js/packages/rtl"
+Log : Info: Output file: ""
+Log : Info: Searching file: examples/System.pp... not found
+Log : Info: Searching file: examples/System.pas... not found
+Log : Info: Searching file: examples/System.p... not found
+Log : Info: Searching file: System.pp... not found
+Log : Info: Searching file: System.pas... not found
+Log : Info: Searching file: System.p... not found
+Log : Info: Searching file: /home/mattias/pas2js/packages/rtl/System.pp... not found
+Log : Info: Searching file: /home/mattias/pas2js/packages/rtl/system.pas... found
+Info: DoUnitAlias Old="Test.Foo.Alias1" New="Bar"
+Log : Info: Searching file: examples/Bar.pp... not found
+Log : Info: Searching file: examples/Bar.pas... not found
+Log : Info: Searching file: examples/Bar.p... not found
+Log : Info: Searching file: Bar.pp... not found
+Log : Info: Searching file: Bar.pas... not found
+Log : Info: Searching file: Bar.p... not found
+Log : Info: Searching file: /home/mattias/pas2js/packages/rtl/Bar.pp... not found
+Log : Info: Searching file: /home/mattias/pas2js/packages/rtl/Bar.pas... not found
+Log : Info: Searching file: /home/mattias/pas2js/packages/rtl/Bar.p... not found
+Log : examples/TestUnitAlias1.pas(8,11) Error: can't find unit "Test.Foo.Alias1"
+Log : Fatal: Compilation aborted
+Error of class "ECompilerTerminate" raised when compiling : Compiler exited with exit code 6
+
+As you can see when searching unit "Test.Foo.Alias1" it searched instead for unit "Bar".

+ 12 - 0
demo/uselibpas2js/examples/TestUnitAlias1.pas

@@ -0,0 +1,12 @@
+unit TestUnitAlias2;
+
+interface
+
+implementation
+
+uses
+  Test.Foo.Alias1; // replaced with bar
+  //Test.Foo.Alias2; // replaced with Test.Foo.SomeLongUnitName
+
+end.
+

+ 163 - 0
demo/uselibpas2js/libpas2jsintf.pas

@@ -0,0 +1,163 @@
+unit LibPas2jsIntf;
+
+{$ifdef fpc}
+{$mode objfpc}{$H+}
+{$endif}
+
+interface
+
+Const
+{$IFDEF UNIX}
+  {$IFDEF darwin}
+  libpas2js = 'libpas2js.dylib';
+  {$DEFINE UseCDecl}
+  {$ELSE}
+  libpas2js = 'libpas2js.so';
+  {$ENDIF}
+{$ELSE}
+  libpas2js = 'libpas2js.dll';
+{$ENDIF}
+
+Type
+  PPas2JSCompiler = Pointer;
+  PDirectoryCache = Pointer;
+  TPas2jsFileAgeTime = longint;
+  TPas2jsFileAttr = longint;
+  TPas2jsFileSize = int64;
+  TLibLogCallBack = Procedure (Data : Pointer; Msg : PAnsiChar; MsgLen : Integer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TWriteJSCallBack = Procedure (Data : Pointer; AFileName: PAnsiChar; AFileNameLen : Integer; AFileData : PAnsiChar; AFileDataLen: Int32); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TReadPasCallBack = Procedure (Data : Pointer; AFileName: PAnsiChar; AFileNameLen : Integer; AFileData : PAnsiChar; Var AFileDataLen: Cardinal); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TReadDirCallBack = Function (Data : Pointer; P: PDirectoryCache; ADirPath: PAnsiChar): boolean; {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TUnitAliasCallBack = Function (Data: Pointer; AUnitName: PAnsiChar; AUnitNameMaxLen: Integer): boolean; {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+
+  TSetPas2JSWriteJSCallBack = Procedure (P : PPas2JSCompiler; ACallBack : TWriteJSCallBack; CallBackData : Pointer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TSetPas2JSCompilerLogCallBack = Procedure (P : PPas2JSCompiler; ACallBack : TLibLogCallBack; CallBackData : Pointer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TSetPas2JSReadPasCallBack = Procedure (P : PPas2JSCompiler; ACallBack : TReadPasCallBack;  CallBackData : Pointer; ABufferSize : Cardinal); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TSetPas2JSReadDirCallBack = Procedure (P : PPas2JSCompiler; ACallBack : TReadDirCallBack;  CallBackData : Pointer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TAddPas2jsDirectoryEntry = procedure(P: PDirectoryCache; AFilename: PAnsiChar; AAge: TPas2jsFileAgeTime; AAttr: TPas2jsFileAttr; ASize: TPas2jsFileSize); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TSetPas2JSUnitAliasCallBack = Procedure (P : PPas2JSCompiler; ACallBack : TUnitAliasCallBack;  CallBackData : Pointer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TRunPas2JSCompiler = Function (P : PPas2JSCompiler; ACompilerExe, AWorkingDir : PAnsiChar; CommandLine : PPAnsiChar; DoReset : Boolean) :Boolean; {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TFreePas2JSCompiler = Procedure (P : PPas2JSCompiler); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TGetPas2JSCompiler = Function () :  PPas2JSCompiler;{$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+  TGetPas2JSCompilerLastError = Procedure(P : PPas2JSCompiler; AError : PAnsiChar; Var AErrorLength : Longint; AErrorClass : PAnsiChar; Var AErrorClassLength : Longint); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+
+Var
+  SetPas2JSWriteJSCallBack : TSetPas2JSWriteJSCallBack;
+  SetPas2JSCompilerLogCallBack : TSetPas2JSCompilerLogCallBack;
+  SetPas2JSReadPasCallBack : TSetPas2JSReadPasCallBack;
+  SetPas2JSReadDirCallBack : TSetPas2JSReadDirCallBack;
+  AddPas2JSDirectoryEntry : TAddPas2jsDirectoryEntry;
+  SetPas2JSUnitAliasCallBack : TSetPas2JSUnitAliasCallBack;
+  RunPas2JSCompiler : TRunPas2JSCompiler;
+  FreePas2JSCompiler : TFreePas2JSCompiler;
+  GetPas2JSCompiler : TGetPas2JSCompiler;
+  GetPas2JSCompilerLastError : TGetPas2JSCompilerLastError;
+
+Function LoadPas2JsLibrary(ALibraryName : String = '') : Integer;
+Function FreePas2jsLibrary : Integer;
+
+implementation
+
+uses
+  {$ifdef fpc}
+  {$ifdef fpc_fullversion<30101}
+  dynlibs,
+  {$endif}
+  {$else}
+  windows,
+  {$endif}
+  sysutils;
+
+{$ifndef fpc}
+type TLibHandle = THandle;
+{$endif}
+
+Var
+  LibHandle : TLibHandle;
+  RefCount : Integer;
+
+Function LoadPas2JsLibrary(ALibraryName : String = '') : Integer;
+
+  Function GPA(N : String) : Pointer ;
+
+  var
+    s: String;
+  begin
+    Result:=GetProcAddress(LibHandle,PChar(N));
+    if Result<>nil then exit;
+    s:=Format('Could not load Pas2JS library function "%s" from "%s"',[N,ALibraryName]);
+    {$IF defined(Unix) and defined(FPC)}
+    s:=s+': '+GetLoadErrorStr;
+    {$ENDIF}
+    Raise Exception.Create(s);
+  end;
+
+var
+  s: String;
+begin
+  if RefCount<>0 then
+    Inc(RefCount)
+  else
+    begin
+    if ALibraryName='' then
+      ALibraryName:=libpas2js;
+    {$ifdef UseDL}
+    LibHandle:=dlopen(Pchar(ALibraryName));
+    {$ELSE}
+    LibHandle:=LoadLibrary(PChar(ALibraryName));
+    {$ENDIF}
+    if (LibHandle=TLibHandle(0)) then
+      begin
+      s:=Format('Could not load Pas2JS library "%s"',[ALibraryName]);
+      {$IF defined(Unix) and defined(FPC)}
+      s:=s+': '+GetLoadErrorStr;
+      {$ENDIF}
+      Raise Exception.Create(s);
+      end;
+    // Compiler
+    Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSWriteJSCallBack):=GPA('SetPas2JSWriteJSCallBack');
+    Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSCompilerLogCallBack):=GPA('SetPas2JSCompilerLogCallBack');
+    Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSReadPasCallBack):=GPA('SetPas2JSReadPasCallBack');
+    Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSReadDirCallBack):=GPA('SetPas2JSReadDirCallBack');
+    Pointer({$IFNDEF FPC}@{$ENDIF}AddPas2JSDirectoryEntry):=GPA('AddPas2JSDirectoryEntry');
+    Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSUnitAliasCallBack):=GPA('SetPas2JSUnitAliasCallBack');
+    Pointer({$IFNDEF FPC}@{$ENDIF}RunPas2JSCompiler):=GPA('RunPas2JSCompiler');
+    Pointer({$IFNDEF FPC}@{$ENDIF}FreePas2JSCompiler):=GPA('FreePas2JSCompiler');
+    Pointer({$IFNDEF FPC}@{$ENDIF}GetPas2JSCompiler):=GPA('GetPas2JSCompiler');
+    Pointer({$IFNDEF FPC}@{$ENDIF}GetPas2JSCompilerLastError):=GPA('GetPas2JSCompilerLastError');
+    RefCount:=1;
+    end;
+  Result:=RefCount;  
+end;
+
+Function FreePas2jsLibrary : Integer;
+
+begin
+  If (RefCount>0) then
+    begin
+    Dec(RefCount);
+    if RefCount=0 then
+      begin
+      {$IFNDEF FPC}
+      FreeLibrary(Libhandle);
+      {$else}
+      UnloadLibrary(Libhandle);
+      {$ENDIF}
+      // Compiler
+      Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSWriteJSCallBack):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSCompilerLogCallBack):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSReadPasCallBack):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSReadDirCallBack):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}AddPas2JSDirectoryEntry):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}SetPas2JSUnitAliasCallBack):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}RunPas2JSCompiler):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}FreePas2JSCompiler):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}GetPas2JSCompiler):=nil;
+      Pointer({$IFNDEF FPC}@{$ENDIF}GetPas2JSCompilerLastError):=nil;
+      end;
+    end;
+  Result:=RefCount;
+end;
+
+end.
+

+ 68 - 0
demo/uselibpas2js/pas2js_unitalias.lpi

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <CompatibilityMode Value="True"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="pas2js_unitalias"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+      <Modes Count="1">
+        <Mode0 Name="default"/>
+      </Modes>
+    </RunParams>
+    <Units Count="3">
+      <Unit0>
+        <Filename Value="pas2js_unitalias.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="libpas2jsintf.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="LibPas2jsIntf"/>
+      </Unit1>
+      <Unit2>
+        <Filename Value="pas2jscompilerproxy.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="Pas2jsCompilerProxy"/>
+      </Unit2>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="pas2js_unitalias"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 21 - 0
demo/uselibpas2js/pas2js_unitalias.lpr

@@ -0,0 +1,21 @@
+program pas2js_unitalias;
+
+uses
+  {$IFDEF FPC}
+  {$IFDEF unix}
+  cmem, cwstring,
+  {$ENDIF}
+  DynLibs,
+  {$ENDIF}
+  SysUtils, LibPas2jsIntf, Pas2jsCompilerProxy;
+
+begin
+  LoadPas2JsLibrary(ExtractFilePath(ParamStr(0))+libpas2js);
+  With TPas2JSCompilerProxy.Create do
+    try
+      Execute;
+    finally
+      Free;
+    end;
+end.
+

+ 241 - 0
demo/uselibpas2js/pas2jscompilerproxy.pas

@@ -0,0 +1,241 @@
+unit Pas2jsCompilerProxy;
+
+{$IFDEF FPC}
+{$mode objfpc}{$H+}
+{$ENDIF}
+
+{$IFDEF darwin}
+{$DEFINE UseCDecl}
+{$ENDIF}
+
+interface
+
+uses
+  Classes, SysUtils, LibPas2jsIntf;
+
+Type
+
+   { TPas2JSCompilerProxy }
+
+   TPas2JSCompilerProxy = class(TObject)
+   Private
+     FCompiler : PPas2JSCompiler;
+     FPasFile: TFileStream;
+   Protected
+     Procedure WriteLog(Const S : AnsiString);
+     Procedure WriteJS(Const AFileName,AFileData : AnsiString);
+     Procedure StartReadPasFile(Const AFileName : AnsiString);
+     Procedure ReadChunk(ABuffer : PAnsiChar; Var AChunkSize : Cardinal);
+     Procedure DoneReadPasFile;
+   Public
+     Constructor Create; virtual;
+     Destructor Destroy; override;
+     Procedure Run(ACompilerExe, AWorkingDir : String; CommandLine : TStringList; DoReset : Boolean);
+     Procedure Execute;
+     Property PasFile : TFileStream Read FPasFile;
+   end;
+
+implementation
+
+{$ifndef fpc}
+const
+  AllFilesMask = '*.*';
+type
+  TUnicodeSearchRec = TSearchRec;
+{$endif}
+
+Procedure DoLog(Data : Pointer; Msg : PansiChar; MsgLen : Integer); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+Var
+  S : AnsiString;
+begin
+  SetLength(S{%H-},MsgLen);
+  if MsgLen>0 then
+    Move(Msg^,S[1],MsgLen);
+  TPas2JSCompilerProxy(Data).WriteLog(S);
+end;
+
+Procedure DoWriteJS(Data : Pointer; AFileName: PAnsiChar; AFileNameLen : Integer;
+  AFileData : PAnsiChar; AFileDataLen: Int32); {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+Var
+  Src,DestFileName : AnsiString;
+begin
+  SetLength(DestFileName{%H-},AFileNameLen);
+  if AFileNameLen>0 then
+    Move(AFileName^,DestFileName[1],AFileNameLen);
+  SetLength(Src{%H-},AFileDataLen);
+  if AFileDataLen>0 then
+    Move(AFileData^,Src[1],AFileDataLen);
+  TPas2JSCompilerProxy(Data).WriteJS(DestFileName,Src);
+end;
+
+
+procedure DoReadPasJS(Data: Pointer; AFileName: PAnsiChar; AFileNameLen: Integer;
+  AFileData: PAnsiChar; Var AFileDataLen: Cardinal);
+  {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+Var
+  DestFileName : AnsiString;
+  BytesToRead : Cardinal;
+begin
+  SetLength(DestFileName{%H-},AFileNameLen);
+  if AFileNameLen>0 then
+    Move(AFileName^,DestFileName[1],AFileNameLen);
+  TPas2JSCompilerProxy(Data).StartReadPasFile(AFileName);
+  BytesToRead:=AFileDatalen;
+  TPas2JSCompilerProxy(Data).ReadChunk(AFileData,AFileDataLen);
+  if AFileDatalen<BytesToRead then
+    TPas2JSCompilerProxy(Data).DoneReadPasFile;
+end;
+
+function DoReadDir(Data: Pointer; P: PDirectoryCache; ADirPath: PAnsiChar): boolean;
+  {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+var
+  Info: TUnicodeSearchRec;
+  Filename: String;
+  Path: PAnsiChar;
+begin
+  if Data=nil then ;
+  Path:=ADirPath;
+  // Note: do not add a 'if not DirectoryExists then exit'.
+  // This will not work on automounted directories. You must use FindFirst.
+  if FindFirst(UnicodeString(Path+AllFilesMask),faAnyFile,Info)=0 then begin
+    repeat
+      // check if special file
+      if (Info.Name='.') or (Info.Name='..') or (Info.Name='')
+      then
+        continue;
+      // add file
+      Filename:=AnsiString(Info.Name);
+      AddPas2JSDirectoryEntry(P,PAnsiChar(Filename),Info.Time,Info.Attr,Info.Size);
+    until FindNext(Info)<>0;
+  end;
+  FindClose(Info);
+  Result:=true;
+end;
+
+Function DoUnitAlias(Data: Pointer; AUnitName: PAnsiChar;
+  AUnitNameMaxLen: Integer): boolean; {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
+var
+  Old, New: AnsiString;
+begin
+  Result:=false;
+  Old:=AUnitName;
+  if Data=nil then ;
+  New:='';
+
+  if SameText(Old,'Test.Foo.Alias1') then
+    New:='Bar'
+  else if SameText(Old,'Test.Foo.Alias2') then
+    New:='Test.Foo.SomeLongUnitName';
+
+  if New<>'' then
+    begin
+    writeln('Info: DoUnitAlias Old="',Old,'" New="',New,'"');
+    if AUnitNameMaxLen<length(New) then
+      raise Exception.Create('unit alias too long');
+    System.Move(New[1],AUnitName^,length(New)+1);
+    Result:=true;
+    end;
+end;
+
+{ TPas2JSCompilerProxy }
+
+procedure TPas2JSCompilerProxy.WriteLog(const S: AnsiString);
+begin
+  Writeln('Log : ',S);
+end;
+
+procedure TPas2JSCompilerProxy.WriteJS(const AFileName, AFileData: AnsiString);
+Var
+  F : TFileStream;
+begin
+  F:=TFileStream.Create(AFileName,fmCreate);
+  try
+    F.WriteBuffer(AFileData[1],Length(AFileData));
+  finally
+    F.Free;
+  end;
+end;
+
+procedure TPas2JSCompilerProxy.StartReadPasFile(const AFileName: AnsiString);
+begin
+  If Assigned(FPasFile) and SameFileName(AFileName,FPasFile.FileName) then
+    exit;
+  FreeAndNil(FPasFile);
+  FPasFile:=TFileStream.Create(aFileName,fmOpenRead or fmShareDenyWrite);
+end;
+
+procedure TPas2JSCompilerProxy.ReadChunk(ABuffer: PAnsiChar; Var AChunkSize: Cardinal);
+begin
+  if Not assigned(FPasFile) then
+    AChunkSize:=0
+  else
+    AChunkSize:=FPasFile.Read(ABuffer^,AChunkSize);
+end;
+
+procedure TPas2JSCompilerProxy.DoneReadPasFile;
+begin
+  FreeAndNil(FPasFile);
+end;
+
+constructor TPas2JSCompilerProxy.Create;
+begin
+  FCompiler:=GetPas2JSCompiler();
+  SetPas2JSCompilerLogCallBack(FCompiler,@DoLog,Self);
+  SetPas2JSWriteJSCallBack(FCompiler,@DoWriteJS,Self);
+  SetPas2JSReadPasCallBack(FCompiler,@DoReadPasJS,Self,16*1024);
+  SetPas2JSReadDirCallBack(FCompiler,@DoReadDir,Self);
+  SetPas2JSUnitAliasCallBack(FCompiler,@DoUnitAlias,Self);
+end;
+
+destructor TPas2JSCompilerProxy.Destroy;
+begin
+  inherited Destroy;
+end;
+
+procedure TPas2JSCompilerProxy.Run(ACompilerExe, AWorkingDir: String; CommandLine: TStringList; DoReset: Boolean);
+Var
+  SCmdLn : Array Of AnsiString;
+  CmdLn : Array Of PAnsiChar;
+  Err,ErrClassname : AnsiString;
+  I,ErrorLength,ErrorClassLength : Integer;
+begin
+  SetLength(SCmdLn{%H-},CommandLine.Count);
+  SetLength(CmdLn{%H-},CommandLine.Count+1);
+  For I:=0 to CommandLine.Count-1 do
+    begin
+    SCmdLn[i]:=CommandLine[i]; // CommandLine[i] might return a temporary string -> make sure it is valid during this proc
+    CmdLn[i]:=PAnsiChar(SCmdLn[i]);
+    end;
+  CmdLn[CommandLine.Count]:=Nil;
+
+  if not RunPas2JSCompiler(FCompiler,PAnsiChar(ACompilerExe),PAnsiChar(AWorkingDir),PPAnsiChar(Cmdln),DoReset) then
+    begin
+    ErrorLength:=1024;
+    ErrorClassLength:=1024;
+    SetLength(Err{%H-},ErrorLength);
+    SetLength(ErrClassname{%H-},ErrorClassLength);
+    GetPas2JSCompilerLastError(FCompiler,@Err[1],ErrorLength,@ErrClassname[1],ErrorClassLength);
+    SetLength(Err,ErrorLength);
+    SetLength(ErrClassname,ErrorClassLength);
+    writeln(Format('Error of class "%s" raised when compiling : %s',[ErrClassname,Err]));
+    ExitCode:=1;
+    end;
+end;
+
+procedure TPas2JSCompilerProxy.Execute;
+Var
+  Cmd : TStringList;
+  I : integer;
+begin
+  Cmd:=TStringList.Create;
+  try
+    for I:=1 to ParamCount do
+      Cmd.Add(Paramstr(i));
+    Run(ParamStr(0),GetCurrentDir,Cmd,False);
+  finally
+    Cmd.Free;
+  end;
+end;
+
+end.
+