⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxjs_symbol.pas

📁 Well known and usefull component for delphi 7
💻 PAS
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////
//    Component: DXJS_SYMBOL
//       Author: Alexander Baranovsky (ab@virtlabor.donbass.com)
//               G.E. Ozz Nixon Jr. (staff@bpdx.com)
// ========================================================================
// Source Owner: DX, Inc. 2002, 2004
//    Copyright: All code is the property of DX, Inc. Licensed for
//               resell by Brain Patchwork DX (tm) and part of the
//               DX (r) product lines, which are (c) 1999-2002
//               DX, Inc. Source may not be distributed without
//               written permission from both Brain Patchwork DX,
//               and DX, Inc.
//      License: (Reminder), None of this code can be added to other
//               developer products without permission. This includes
//               but not limited to DCU's, DCP's, DLL's, OCX's, or
//               any other form of merging our technologies. All of
//               your products released to a public consumer be it
//               shareware, freeware, commercial, etc. must contain a
//               license notification somewhere visible in the
//               application.
// Code Version: (3rd Generation)
// ========================================================================
//  Description: Symbol Table Manager
// ========================================================================
////////////////////////////////////////////////////////////////////////////

unit DXJS_SYMBOL;
interface
{$I DXJavaScript.def}

uses
   Classes,
{$IFDEF VARIANTS}
   Variants,
{$ENDIF}
   DXJS_SHARE,
   DXJS_LIST;

type
   TNames=TStringList;

   TSymbolRec=packed record
      PName:Integer;
      Kind:byte;
      PType:SmallInt;
      Count:SmallInt;
      Level:SmallInt;
      Next:SmallInt;
      Module:SmallInt;
      Entry:SmallInt;
      Address:Pointer;
      CRC:Integer;
   end;

   TMem=pointer;

   TSymbolTable=class
//713      Debug:Boolean;
      JScript:Pointer;
      A:array[0..MaxSymbolCard] of TSymbolRec;
//      ShortCut:String; //803
      Card:Integer;
      Names:TNames;
      Mem:TMem;
      MemBoundVar,MemBoundConst,EvalMemBoundVar:Integer;
      FIRST_CONST,LAST_CONST:Integer;
      TrueID,FalseID:Integer;
      UndefinedID,NullID,InfinityID,NaNID,ArrayID,RegExpID,FunctionID:Integer;
      CreateCard,ParseCard,EvalCard:Integer;
      HashArray:THashArray;
      constructor Create (ABScript:Pointer) ;
      destructor Destroy;override;
      procedure AllocateEvalSpace;
      procedure SetupStandardDefinitions;
      procedure SetupHostDefinitions;
      function AppNativeRoutine (const Name:string;Address:Pointer;
         Len:Integer;
         KindProc:TKindProc=KindJavaScript) :Integer;
      function AppHostRoutine (const Name:string;Address:Pointer;
         Len:Integer;
         KindProc:TKindProc=KindJavaScript) :Integer;
      procedure SetName (Const I:Integer;const Name:string) ;
      function GetName (Const I:Integer) :string;
      function GetKind (Const I:Integer) :Integer;
      function GetStrKind (I:Integer) :string;
      function GetStrType (Const I:Integer) :string;
      function IsBaseType (Const TypeID:Integer) :boolean;
      function GetStrVal (Const I:Integer) :string;
      function SetSizeOfSubFrame (Const SubID:Integer) :Integer;
      function GetSizeOfSubFrame (Const SubID:Integer) :Integer;
      function GetAddrOfSubFrame (Const SubID:Integer) :Pointer;
      procedure AllocateSub (Const SubID:Integer) ;
      procedure DeallocateSub (Const SubID:Integer) ;
      function SetEndOfSub (Const SubID:Integer) :Integer;
      function GetEndOfSub (Const SubID:Integer) :Integer;
      function GetParamID (Const SubID,N:Integer) :Integer;
      function GetSizeOf (Const I:Integer) :Integer;
      function GetActualSizeOf (Const I:Integer) :Integer;
      function AllocateVar (Const I:Integer) :Pointer;
      function AllocateConst (Const I:Integer) :Pointer;

      function AppLabel:Integer;
      function AppDelphiObject (const Name:string;const Instance:TObject) :Integer;

      function GetVariant (Const ID:Integer) :TVariant;
      procedure ClearVariant (Const ID:Integer) ;
      procedure PutVariant (Const ID:Integer;const Val:TVariant) ;
      function AppVariant (const Val:TVariant) :Integer;
      function AppVariantConst (const Val:TVariant) :Integer;
//reference
      function AppReference (const Base:TVariant;
         const PropertyName:string) :Integer;
      procedure SetReference (Const ID:Integer;const Base:TVariant;
         const PropertyName:string) ;
      function GetBase (Const RefID:Integer) :TVariant;
      function GetPropertyName (Const RefID:Integer) :string;
      function GetValue (Const ID:Integer) :TVariant;
      procedure PutValue (Const ID:Integer;const Val:TVariant) ;
      function Delete (Const ID:Integer) :boolean;

      function CodeNumberConst (const StrVal:string) :Integer;
      function CodeStringConst (const StrVal:string) :Integer;

      function LookUpID (const Name:string;aLevel:Integer) :Integer;
      function FastLookUpID (const Name:string;aLevel:Integer) :Integer;
      function LookupConstID (const Value:Variant) :Integer;

      procedure Erase (Const I:Integer) ;
      procedure EraseTail (Const Bound:Integer) ;

      procedure Print (const FileName:string) ;
      function IsOutsideMemAddress (A:Pointer) :boolean;
      function IsInsideMemAddress (A:Pointer) :boolean;
      function IsExternalAddress (A:Pointer) :boolean;
      function IsInternalAddress (A:Pointer) :boolean;

      function AppThisID (Const SubID:Integer) :Integer;
      function GetThisID (Const SubID:Integer) :Integer;

      procedure SaveToStream (S:TStream) ;
      procedure LoadFromStream (S:TStream) ;
      procedure SaveRec (Const I:Integer;S:TStream) ;
      procedure LoadRec (Const I:Integer;S:TStream) ;
      procedure ResetRun;
      procedure Enum (Variables,Functions,Constants:TStringList) ;
   end;

implementation

uses
   SysUtils,// IntToStr, StrToInt, StrToFloat
   DXString,
   DXJS_MAIN,
   DXJS_EXTERN,
   DXJS_OBJECT,
   DXJS_CONV;

constructor TSymbolTable.Create (ABScript:Pointer) ;
var
   Loop:Integer;

begin
//   Debug:=False;
   Names:=TNames.Create;
   Names.AddObject('***',TObject(DXString.CRC32ByString('***',$FFFF)));
   HashArray:=THashArray.Create;
   JScript:=ABScript;
   GetMem (Mem,MaxMem) ;
   FillChar2 (Mem^,MaxMem,#0) ;
   MemBoundConst:=StartMemBoundConst;// 100
   MemBoundVar:=StartMemBoundVar;// 40000
//   ShortCut:=',';

   FillChar2 (A,SizeOf (A) ,#0) ;
   for Loop:=1 to BaseTypes.Card do begin
      SetName (Loop,BaseTypes.A[Loop].Name) ;
      A[Loop].Kind:=kind_is_TYPE;
   end;
   FIRST_CONST:=BaseTypes.Card+1;
   LAST_CONST:=FIRST_CONST+MaxConst;
   Card:=LAST_CONST+1;
   TrueID:=AppVariantConst (true) ;
   SetName (TrueID,     'true') ;
   FalseID:=AppVariantConst (false) ;
   SetName (FalseID,    'false') ;
   UndefinedID:=AppVariantConst (Undefined) ;
   SetName (UndefinedID,'undefined') ;
   NullID:=AppVariantConst (Null) ;
   SetName (NullID,     'null') ;
   InfinityID:=AppVariantConst (Infinity) ;
   SetName (InfinityID, 'infinity') ;
   NaNID:=AppVariantConst (NaN) ;
   SetName (NaNID,      'NaN') ;
   ArrayID:=0;
   RegExpID:=0;
   SetupStandardDefinitions;
   CreateCard:=Card;
   ParseCard:=CreateCard;
   EvalCard:=ParseCard;
   EvalMemBoundVar:=MemBoundVar;
//   Debug:=True;
end;

destructor TSymbolTable.Destroy;
var
   Loop:Integer;
begin
   for Loop:=Card downto 1 do Erase (Loop) ;
   Names.Free;
   FreeMem (Mem,MaxMem) ;
   HashArray.Free;
   inherited;
end;

procedure TSymbolTable.SaveRec (Const I:Integer;S:TStream) ;
begin
   S.WriteBuffer (A[I],SizeOf (TSymbolRec) ) ;
   if A[I].PName>0 then SaveString (Names[A[I].PName] ,S) ;
   if A[I].Address<>nil then SaveValue (GetVariant (I) ,S) ;
end;

procedure TSymbolTable.LoadRec (Const I:Integer;S:TStream) ;
var
   Name:string;
   V:Variant;
begin
   S.ReadBuffer (A[I],SizeOf (TSymbolRec) ) ;
   if A[I].PName>0 then begin
      Name:=LoadString (S) ;
      SetName (I,Name) ;
   end;
   if A[I].Address<>nil then begin
      if A[I].Kind=Kind_is_Const then AllocateConst (I)
      else AllocateVar (I) ;
      V:=LoadValue (S,JScript) ;
      PutVariant (I,V) ;
   end;
end;

procedure TSymbolTable.SaveToStream (S:TStream) ;
var
   Loop:Integer;

begin
   SaveInteger (FIRST_CONST,S) ;
   SaveInteger (CreateCard,S) ;
   SaveInteger (ParseCard,S) ;
   for Loop:=BaseTypes.Card+1 to FIRST_CONST-1 do SaveRec (Loop,S) ;
   for Loop:=CreateCard+1 to ParseCard do SaveRec (Loop,S) ;
end;

procedure TSymbolTable.LoadFromStream (S:TStream) ;
var
   Loop:Integer;

begin
   FIRST_CONST:=LoadInteger (S) ;
   CreateCard:=LoadInteger (S) ;
   ParseCard:=LoadInteger (S) ;
   Card:=ParseCard;
   for Loop:=BaseTypes.Card+1 to FIRST_CONST-1 do LoadRec (Loop,S) ;
   for Loop:=CreateCard+1 to ParseCard do LoadRec (Loop,S) ;
   AllocateEvalSpace;
end;

procedure TSymbolTable.AllocateEvalSpace;
begin
   EvalCard:=ParseCard;
   EvalMemBoundVar:=MemBoundVar;
   Inc (Card,MaxEval) ;
   Inc (MemBoundVar,MaxEval*SizeOf (TVariant) ) ;
end;

procedure TSymbolTable.SetupStandardDefinitions;

   procedure AddStandardObject (ClassID:Integer;SO:TScriptObject) ;
   var
      ID:Integer;
      D:TDefinition;
      Loop:Integer;
      Name:string;

   begin
      ID:=AppVariant (ScriptObjectToVariant (SO) ) ;
      SetName (ID,StandardClasses[ClassID]) ;
      if SO.Prototype=nil then Exit;
      with TJScript (JScript) do begin
         ID:=LookUpID ('__'+StandardClasses[ClassID],0) ;
         if ID>0 then begin
            SO.Prototype.PutProperty ('constructor',GetVariant (ID) ) ;
            for Loop:=0 to StdDefinitionList.Count-1 do begin
               D:=TDefinition (StdDefinitionList.Objects[Loop]) ;
               if D.ClassID=ClassID then begin
                  Name:='__'+StandardClasses[ClassID]+'_'+StdDefinitionList[Loop];
                  ID:=LookUpID (Name,0) ;
                  SO.Prototype.PutProperty (StdDefinitionList[Loop],GetVariant (ID) ) ;
               end;
            end;
         end;
      end;
   end;

var
   Loop,SubID:Integer;
   D:TDefinition;
   S,Ws:string;
begin
   for Loop:=0 to TJScript (JScript) .StdDefinitionList.Count-1 do begin
      D:=TDefinition (TJScript (JScript) .StdDefinitionList.Objects[Loop]) ;
      SubID:=AppNativeRoutine (TJScript (JScript) .
         StdDefinitionList[Loop],D.Address,D.Len,D.KindProc) ;
      Ws:=GetName(subID);
      if IsStandardClass (D.ClassID) then begin
         S:='__'+StandardClasses[D.ClassID]+'_'+Ws ;
         SetName (SubID,S) ;
      end
      // dynamically assign the ID for the first instance of each:
      Else if Ws='__Array' then ArrayID:=SubID
      Else If Ws='__RegExp' then RegExpID:=SubID
      Else If Ws='__Function' then FunctionID:=SubID;
   end;
   AddStandardObject (Math_ID,TMathObject.Create (JScript) ) ;
   AddStandardObject (Date_ID,TJScript (JScript) .GlobalObject.DateObject) ;
   AddStandardObject (Boolean_ID,TBooleanObject.Create (false,JScript) ) ;
   AddStandardObject (Number_ID,TNumberObject.Create (Integer (0) ,JScript) ) ;
   AddStandardObject (String_ID,TStringObject.Create ('',JScript) ) ;
   AddStandardObject (Array_ID,TArrayObject.Create (JScript) ) ;
   AddStandardObject (RegExp_ID,TJScript (JScript) .GlobalObject.RegExpObject) ;
   AddStandardObject (Function_ID,TFunctionObject.Create ('',FunctionID,@__Function,0,JScript) ) ;
   AddStandardObject (Error_ID,TErrorObject.Create (JScript) ) ;
   AddStandardObject (DelphiObject_ID,TDelphiObject.Create (nil,JScript) ) ;
   AddStandardObject (ActiveXObject_ID,TActiveXObject.Create (Undefined,JScript) ) ;
   AddStandardObject (EnumeratorObject_ID,TEnumeratorObject.Create (Undefined,JScript) ) ;
end;

procedure TSymbolTable.SetupHostDefinitions;
var
   Loop,ID:Integer;
   P:Pointer;
   D:TDefinition;

begin
   with TJScript (JScript) do begin
      for Loop:=0 to HostDefinitionList.Count-1 do begin
         D:=TDefinition (HostDefinitionList.Objects[Loop]) ;
         AppHostRoutine (HostDefinitionList[Loop],D.Address,D.Len,D.KindProc) ;
      end;
      for Loop:=0 to HostVariableList.Count-1 do begin
         P:=Pointer (HostVariableList.Objects[Loop]) ;
         ID:=AppVariant (Variant (Variant (P^) ) ) ;
         SetName (ID,HostVariableList[Loop]) ;
      end;
      for Loop:=0 to ConstantList.Count-1 do begin
         P:=Pointer (ConstantList.Objects[Loop]) ;
         ID:=AppVariantConst (Variant (Variant (P^) ) ) ;
         SetName (ID,ConstantList[Loop]) ;
      end;
      for Loop:=0 to HostObjectList.Count-1 do
         AppDelphiObject (HostObjectList[Loop],HostObjectList.Objects[Loop]) ;
   end;
end;

function TSymbolTable.AppNativeRoutine (const Name:string;Address:Pointer;
   Len:Integer;KindProc:TKindProc=KindJavaScript) :Integer;

var
   SubDef:string;
   SO:TScriptObject;

begin
   result:=AppVariant (Undefined) ;
   SetName (result,Name) ;
   A[result].Kind:=kind_is_SUB;
   AppThisID (result) ;
   SetEndOfSub (result) ;
   SetSizeOfSubFrame (result) ;
   SubDef:='function '+GetName (result) +'(){ [ native routine code ] }';
   SO:=TFunctionObject.Create (SubDef,result,Address,Len,JScript) ;
   SO.KindProc:=KindProc;
   PutVariant (result,ScriptObjectToVariant (SO) ) ;
end;

function TSymbolTable.AppHostRoutine (const Name:string;Address:Pointer;
   Len:Integer;KindProc:TKindProc=KindJavaScript) :Integer;

var
   SubDef:string;
   SO:TScriptObject;

begin
   result:=LookUpID (Name,0) ;
   if result=0 then begin
      result:=AppVariant (Undefined) ;
      SetName (result,Name) ;
      A[result].Kind:=kind_is_SUB;
      AppThisID (result) ;
      SetEndOfSub (result) ;
      SetSizeOfSubFrame (result) ;
   end;
   A[result].Kind:=kind_is_SUB;
   SubDef:='function '+GetName (result) +'(){ [ native host code ] }';
   SO:=TFunctionObject.Create (SubDef,result,Address,Len,JScript) ;
   SO.KindProc:=KindProc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -