wasm.pas2js.regexp.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. unit wasm.pas2js.regexp;
  2. {$mode ObjFPC}
  3. { $define NOLOGAPICALLS}
  4. interface
  5. uses
  6. sysutils, js, wasienv, weborworker, wasm.regexp.shared, types;
  7. Type
  8. PByte = TWasmPointer;
  9. PLongint = TWasmPointer;
  10. TIndexArray = Array[0..1] of Longint;
  11. { TWasmRegexp }
  12. TWasmRegexp = Class(TObject)
  13. private
  14. FID: TWasmRegexpID;
  15. FRegExp: TJSRegExp;
  16. FRes: TJSObject;
  17. FGroupNames : TStringDynArray;
  18. procedure GetGroupNames;
  19. Public
  20. Constructor Create(aRegex : TJSRegexp; aID : TWasmRegexpID);
  21. Procedure Exec(S : String);
  22. Function Test(S : String) : Boolean;
  23. Function HaveResult : Boolean;
  24. Function ResultIndex : Integer;
  25. Function ResultMatchCount : Integer;
  26. Function GetMatch(aIndex: Integer) : String;
  27. Function GetMatchIndexes(aIndex: Integer) : TIndexArray;
  28. Function GetGroupIndexes(aName: String) : TIndexArray;
  29. Function GetGroupCount : Integer;
  30. Function GetGroupName(aIndex : Integer) : String;
  31. Function GetGroupValue(const aName : String) : String;
  32. Property RegExp : TJSRegExp Read FRegExp;
  33. Property Res : TJSObject Read FRes;
  34. Property ID : TWasmRegexpID Read FID;
  35. end;
  36. { TWasmRegExpAPI }
  37. TWasmRegExpAPI = class(TImportExtension)
  38. Private
  39. FLogAPICalls: Boolean;
  40. FNextID : TWasmRegexpID;
  41. FRegExps : TJSObject;
  42. protected
  43. procedure DoError(const Msg : String);
  44. Procedure DoError(Const Fmt : String; const Args : Array of const);
  45. Procedure LogCall(const Msg : String);
  46. Procedure LogCall(Const Fmt : String; const Args : Array of const);
  47. Function GetNextID : TWasmRegExpID;
  48. Function FindRegExp(aID : TWasmRegExpID) : TWasmRegExp;
  49. function RegExpAllocate(aExpr : PByte; aExprLen : longint; aFlags : Longint; aID : PWasmRegExpID) : TWasmRegexpResult;
  50. function RegExpDeallocate(aExprID : TWasmRegExpID) : TWasmRegexpResult;
  51. function RegExpExec(aExprID : TWasmRegExpID; aString : PByte; aStringLen :Longint; aIndex : PLongint; aResultCount : PLongint) : TWasmRegexpResult;
  52. function RegExpTest(aExprID : TWasmRegExpID; aString : PByte; aStringLen :Longint; aResult : PLongint) : TWasmRegexpResult;
  53. function RegExpGetFlags(aExprID : TWasmRegExpID; aFlags : PLongint) : TWasmRegexpResult;
  54. function RegExpGetExpression(aExprID : TWasmRegExpID; aExp : PByte; aExpLen : PLongint) : TWasmRegexpResult;
  55. function RegExpGetLastIndex(aExprID : TWasmRegExpID; aLastIndex : PLongint) : TWasmRegexpResult;
  56. function RegExpGetResultMatch(aExprID : TWasmRegExpID; aIndex : Longint; Res : PByte; ResLen : PLongint) : TWasmRegexpResult;
  57. function RegExpGetGroupCount(aExprID : TWasmRegExpID; aCount: PLongint) : TWasmRegexpResult;
  58. function RegExpGetGroupName(aExprID : TWasmRegExpID; aIndex : Longint; aName : PByte; aNameLen : PLongint) : TWasmRegexpResult;
  59. function RegExpGetNamedGroup(aExprID : TWasmRegExpID; aName : PByte; aNameLen : Longint; aValue : PByte; aValueLen: PLongint) : TWasmRegexpResult;
  60. function RegExpGetIndexes(aExprID : TWasmRegExpID; aIndex : Longint; aStartIndex : PLongint; aStopIndex: PLongint) : TWasmRegexpResult; ;
  61. function RegExpGetNamedGroupIndexes(aExprID : TWasmRegExpID; aName : PByte; aNameLen : Integer; aStartIndex : PLongint; aStopIndex: PLongint) : TWasmRegexpResult;
  62. Public
  63. constructor Create(aEnv: TPas2JSWASIEnvironment); override;
  64. procedure FillImportObject(aObject: TJSObject); override;
  65. function ImportName: String; override;
  66. Property LogAPICalls : Boolean Read FLogAPICalls Write FLogAPICalls;
  67. end;
  68. implementation
  69. { TWasmRegexp }
  70. constructor TWasmRegexp.Create(aRegex: TJSRegexp; aID: TWasmRegexpID);
  71. begin
  72. FRegExp:=aRegex;
  73. FID:=aID;
  74. end;
  75. procedure TWasmRegexp.Exec(S: String);
  76. begin
  77. FRes:=FRegExp.ExecFull(S);
  78. end;
  79. function TWasmRegexp.Test(S: String): Boolean;
  80. begin
  81. Result:=FRegexp.test(S);
  82. end;
  83. function TWasmRegexp.HaveResult: Boolean;
  84. begin
  85. Result:=Assigned(FRes);
  86. end;
  87. function TWasmRegexp.ResultIndex: Integer;
  88. var
  89. Tmp : JSValue;
  90. begin
  91. Result:=-1;
  92. if Not HaveResult then
  93. exit;
  94. Tmp:=FRes['index'];
  95. If isNumber(Tmp) then
  96. Result:=Integer(Tmp);
  97. end;
  98. function TWasmRegexp.ResultMatchCount: Integer;
  99. var
  100. Tmp : JSValue;
  101. begin
  102. Result:=0;
  103. if Not HaveResult then
  104. exit;
  105. Tmp:=FRes['length'];
  106. If isNumber(Tmp) then
  107. Result:=Integer(Tmp);
  108. end;
  109. function TWasmRegexp.GetMatch(aIndex: Integer): String;
  110. begin
  111. Result:='';
  112. if Not HaveResult then
  113. exit;
  114. if (aIndex>=0) and (aIndex<ResultMatchCount) then
  115. Result:=String(FRes[IntToStr(aIndex)])
  116. else
  117. Raise Exception.CreateFmt('Index %d out of bounds [0..%d[',[aIndex,ResultMatchCount]);
  118. end;
  119. function TWasmRegexp.GetMatchIndexes(aIndex: Integer): TIndexArray;
  120. var
  121. Tmp : JSValue;
  122. Arr : TJSArray absolute tmp;
  123. Tmp2 : JSValue;
  124. Arr2 : TJSArray absolute tmp2;
  125. begin
  126. Result[0]:=-1;
  127. Result[1]:=-1;
  128. if Not HaveResult then
  129. Exit;
  130. if pos('d',RegExp.Flags)=0 then
  131. Exit;
  132. if (aIndex<0) or (aIndex>=ResultMatchCount) then
  133. Exit;
  134. Tmp:=FRes['indices'];
  135. if not isArray(Tmp) then
  136. exit;
  137. if (aIndex<0) or (aIndex>=Arr.length) then
  138. Raise Exception.CreateFmt('Index %d out of bounds [0..%d[',[aIndex,ResultMatchCount]);
  139. Tmp2:=Arr[aIndex];
  140. if not isArray(Tmp2) then
  141. exit;
  142. Result[0]:=Integer(Arr2[0]);
  143. Result[1]:=Integer(Arr2[1]);
  144. end;
  145. function TWasmRegexp.GetGroupIndexes(aName: String): TIndexArray;
  146. var
  147. Tmp : JSValue;
  148. Obj : TJSObject absolute tmp;
  149. Tmp2 : JSValue;
  150. lGroups : TJSObject absolute tmp2;
  151. Res: JSValue;
  152. Arr2 : TJSArray absolute Res;
  153. begin
  154. Result[0]:=-1;
  155. Result[1]:=-1;
  156. if Not HaveResult then
  157. Exit;
  158. if pos('d',RegExp.Flags)=0 then
  159. Exit;
  160. Tmp:=FRes['indices'];
  161. if not isArray(Tmp) then
  162. exit;
  163. Tmp2:=Obj['groups'];
  164. if Not isObject(Tmp) then
  165. exit;
  166. Res:=lGroups[aName];
  167. if Not isArray(Res) then
  168. exit;
  169. Result[0]:=Integer(Arr2[0]);
  170. Result[1]:=Integer(Arr2[1]);
  171. end;
  172. procedure TWasmRegexp.GetGroupNames;
  173. var
  174. Tmp : JSValue;
  175. begin
  176. if Not HaveResult then
  177. Exit;
  178. Tmp:=FRes['groups'];
  179. if Not isObject(Tmp) then
  180. exit;
  181. FGroupNames:=TJSObject.getOwnPropertyNames(TJSObject(Tmp));
  182. end;
  183. function TWasmRegexp.GetGroupCount : Integer;
  184. begin
  185. Result:=0;
  186. if Not HaveResult then
  187. Exit;
  188. If Length(FGroupNames)=0 then
  189. GetGroupNames;
  190. Result:=Length(FGroupNames);
  191. end;
  192. function TWasmRegexp.GetGroupName(aIndex: Integer): String;
  193. begin
  194. if (aIndex>=0) and (aIndex<Length(FGroupNames)) then
  195. Result:=FGroupNames[aIndex]
  196. else
  197. Result:='';
  198. end;
  199. function TWasmRegexp.GetGroupValue(const aName: String): String;
  200. var
  201. Tmp : JSValue;
  202. lGroups : TJSObject absolute Tmp;
  203. Res : JSValue;
  204. begin
  205. Result:='';
  206. Tmp:=FRes['groups'];
  207. if isObject(Tmp) then
  208. begin
  209. Res:=lGroups[aName];
  210. if isString(Res) then
  211. Result:=String(Res);
  212. end;
  213. end;
  214. { TWasmRegExpAPI }
  215. function TWasmRegExpAPI.RegExpAllocate(aExpr: PByte; aExprLen: longint; aFlags: Longint; aID: PWasmRegExpID): TWasmRegexpResult;
  216. var
  217. lRegexp,lFlags : String;
  218. Regex : TJSRegexp;
  219. lID : TWasmRegexpID;
  220. begin
  221. lRegExp:=env.GetUTF8StringFromMem(aExpr,aExprLen);
  222. lFlags:=RegexpFlagsToString(aFlags);
  223. {$IFNDEF NOLOGAPICALLS}
  224. If LogAPICalls then
  225. LogCall('RegExp.Allocate("%s","%s",[%x])',[lRegExp,lFlags,aID]);
  226. {$ENDIF}
  227. if (lRegexp='') then
  228. Exit(WASMRE_RESULT_NO_REGEXP);
  229. lID:=GetNextID;
  230. try
  231. Regex:=TJSRegExp.New(lRegExp,lFlags);
  232. except
  233. Exit(WASMRE_RESULT_ERROR);
  234. end;
  235. FRegexps[IntToStr(lID)]:=TWasmRegexp.Create(Regex,lID);
  236. env.SetMemInfoInt32(aID,lID);
  237. Result:=WASMRE_RESULT_SUCCESS;
  238. {$IFNDEF NOLOGAPICALLS}
  239. If LogAPICalls then
  240. LogCall('RegExp.Allocate("%s","%s",[%x]) => %d',[lRegexp,lFlags,aID,lID]);
  241. {$ENDIF}
  242. end;
  243. function TWasmRegExpAPI.RegExpDeallocate(aExprID: TWasmRegExpID): TWasmRegexpResult;
  244. var
  245. lRegExp : TWasmRegExp;
  246. begin
  247. {$IFNDEF NOLOGAPICALLS}
  248. If LogAPICalls then
  249. LogCall('RegExp.Deallocate(%d)',[aExprID]);
  250. {$ENDIF}
  251. lRegExp:=FindRegExp(aExprID);
  252. if lRegExp=Nil then
  253. Exit(WASMRE_RESULT_INVALIDID)
  254. end;
  255. function TWasmRegExpAPI.RegExpExec(aExprID: TWasmRegExpID; aString: PByte; aStringLen: Longint; aIndex: PLongint;
  256. aResultCount: PLongint): TWasmRegexpResult;
  257. var
  258. lRegExp : TWasmRegExp;
  259. S : String;
  260. begin
  261. S:=Env.GetUTF8StringFromMem(aString,aStringLen);
  262. {$IFNDEF NOLOGAPICALLS}
  263. If LogAPICalls then
  264. LogCall('RegExp.Exec(%d,"%s",[%x],[%x])',[aExprID,S,aIndex,aResultCount]);
  265. {$ENDIF}
  266. lRegExp:=FindRegExp(aExprID);
  267. if lRegExp=Nil then
  268. Exit(WASMRE_RESULT_INVALIDID);
  269. try
  270. lRegExp.Exec(S);
  271. except
  272. Exit(WASMRE_RESULT_ERROR);
  273. end;
  274. Env.SetMemInfoInt32(aIndex,lRegexp.ResultIndex);
  275. Env.SetMemInfoInt32(aResultCount,lRegexp.ResultMatchCount);
  276. Result:=WASMRE_RESULT_SUCCESS;
  277. end;
  278. function TWasmRegExpAPI.RegExpTest(aExprID: TWasmRegExpID; aString: PByte; aStringLen: Longint; aResult: PLongint
  279. ): TWasmRegexpResult;
  280. var
  281. lRegExp : TWasmRegExp;
  282. B : Boolean;
  283. S : String;
  284. begin
  285. S:=Env.GetUTF8StringFromMem(aString,aStringLen);
  286. {$IFNDEF NOLOGAPICALLS}
  287. If LogAPICalls then
  288. LogCall('RegExp.Exec(%d,"%s",[%x])',[aExprID,S,aResult]);
  289. {$ENDIF}
  290. lRegExp:=FindRegExp(aExprID);
  291. if lRegExp=Nil then
  292. Exit(WASMRE_RESULT_INVALIDID);
  293. if lRegExp=Nil then
  294. Exit(WASMRE_RESULT_INVALIDID);
  295. try
  296. B:=lRegExp.Test(S);
  297. except
  298. Exit(WASMRE_RESULT_ERROR);
  299. end;
  300. Env.SetMemInfoInt32(aResult,Ord(B));
  301. Result:=WASMRE_RESULT_SUCCESS;
  302. end;
  303. function TWasmRegExpAPI.RegExpGetFlags(aExprID: TWasmRegExpID; aFlags: PLongint): TWasmRegexpResult;
  304. var
  305. lRegExp : TWasmRegExp;
  306. lFlags : Longint;
  307. begin
  308. {$IFNDEF NOLOGAPICALLS}
  309. If LogAPICalls then
  310. LogCall('RegExp.GetFlags(%d,[%x])',[aExprID,aFlags]);
  311. {$ENDIF}
  312. lRegExp:=FindRegExp(aExprID);
  313. if lRegExp=Nil then
  314. Exit(WASMRE_RESULT_INVALIDID);
  315. lFlags:=StringToRegexpFlags(lRegexp.RegExp.Flags);
  316. Env.SetMemInfoInt32(aFlags,lFLags);
  317. Result:=WASMRE_RESULT_SUCCESS;
  318. end;
  319. function TWasmRegExpAPI.RegExpGetExpression(aExprID: TWasmRegExpID; aExp: PByte; aExpLen: PLongint): TWasmRegexpResult;
  320. var
  321. lRegExp : TWasmRegExp;
  322. lOldLen,lLen : Integer;
  323. begin
  324. {$IFNDEF NOLOGAPICALLS}
  325. If LogAPICalls then
  326. LogCall('RegExp.GetExpression(%d,[%x],[%x])',[aExprID,aExp,aExpLen]);
  327. {$ENDIF}
  328. lRegExp:=FindRegExp(aExprID);
  329. if lRegExp=Nil then
  330. Exit(WASMRE_RESULT_INVALIDID);
  331. lOldLen:=Env.GetMemInfoInt32(aExpLen);
  332. lLen:=Env.SetUTF8StringInMem(aExp,lOldLen,lRegexp.RegExp.Source);
  333. Env.SetMemInfoInt32(aExpLen,abs(lLen));
  334. if lLen<0 then
  335. Exit(WASMRE_RESULT_NO_MEM);
  336. Result:=WASMRE_RESULT_SUCCESS;
  337. end;
  338. function TWasmRegExpAPI.RegExpGetLastIndex(aExprID: TWasmRegExpID; aLastIndex: PLongint): TWasmRegexpResult;
  339. var
  340. lRegExp : TWasmRegExp;
  341. begin
  342. {$IFNDEF NOLOGAPICALLS}
  343. If LogAPICalls then
  344. LogCall('RegExp.Deallocate(%d)',[aExprID]);
  345. {$ENDIF}
  346. lRegExp:=FindRegExp(aExprID);
  347. if lRegExp=Nil then
  348. Exit(WASMRE_RESULT_INVALIDID);
  349. Env.SetMemInfoInt32(aLastIndex,lRegexp.RegExp.lastIndex);
  350. end;
  351. function TWasmRegExpAPI.RegExpGetResultMatch(aExprID: TWasmRegExpID; aIndex: Longint; Res: PByte; ResLen: PLongint
  352. ): TWasmRegexpResult;
  353. var
  354. lRegExp : TWasmRegExp;
  355. S : String;
  356. lOldLen,lLen : Integer;
  357. begin
  358. {$IFNDEF NOLOGAPICALLS}
  359. If LogAPICalls then
  360. LogCall('RegExp.GetResultMatch(%d,%d,[%x],[%x])',[aExprID,aIndex,Res,ResLen]);
  361. {$ENDIF}
  362. lRegExp:=FindRegExp(aExprID);
  363. if lRegExp=Nil then
  364. Exit(WASMRE_RESULT_INVALIDID);
  365. if (aIndex<0) or (aIndex>=lRegExp.ResultMatchCount) then
  366. Exit(WASMRE_RESULT_INVALIDIDX);
  367. S:=lRegExp.GetMatch(aIndex);
  368. lOldLen:=Env.GetMemInfoInt32(ResLen);
  369. lLen:=Env.SetUTF8StringInMem(Res,lOldLen,S);
  370. Env.SetMemInfoInt32(ResLen,abs(lLen));
  371. if lLen<0 then
  372. Exit(WASMRE_RESULT_NO_MEM);
  373. Result:=WASMRE_RESULT_SUCCESS;
  374. end;
  375. function TWasmRegExpAPI.RegExpGetGroupCount(aExprID: TWasmRegExpID; aCount: PLongint): TWasmRegexpResult;
  376. var
  377. lRegExp : TWasmRegExp;
  378. begin
  379. {$IFNDEF NOLOGAPICALLS}
  380. If LogAPICalls then
  381. LogCall('RegExp.GetGroupCount(%d,[%x])',[aExprID,aCount]);
  382. {$ENDIF}
  383. lRegExp:=FindRegExp(aExprID);
  384. if lRegExp=Nil then
  385. Exit(WASMRE_RESULT_INVALIDID);
  386. Env.SetMemInfoInt32(aCount,lRegexp.GetGroupCount);
  387. Result:=WASMRE_RESULT_SUCCESS;
  388. end;
  389. function TWasmRegExpAPI.RegExpGetGroupName(aExprID: TWasmRegExpID; aIndex: Longint; aName: PByte; aNameLen: PLongint
  390. ): TWasmRegexpResult;
  391. var
  392. lRegExp : TWasmRegExp;
  393. S : String;
  394. lOldLen,lLen : Integer;
  395. begin
  396. {$IFNDEF NOLOGAPICALLS}
  397. If LogAPICalls then
  398. LogCall('RegExp.GetGroupName(%d,%d,[%x],[%x])',[aExprID,aIndex,aName,aNameLen]);
  399. {$ENDIF}
  400. lRegExp:=FindRegExp(aExprID);
  401. if lRegExp=Nil then
  402. Exit(WASMRE_RESULT_INVALIDID);
  403. if (aIndex<0) or (aIndex>=lRegExp.GetGroupCount) then
  404. Exit(WASMRE_RESULT_INVALIDIDX);
  405. S:=lRegExp.GetGroupName(aIndex);
  406. lOldLen:=Env.GetMemInfoInt32(aNameLen);
  407. lLen:=Env.SetUTF8StringInMem(aName,lOldLen,S);
  408. Env.SetMemInfoInt32(aNameLen,abs(lLen));
  409. if lLen<0 then
  410. Exit(WASMRE_RESULT_NO_MEM);
  411. Result:=WASMRE_RESULT_SUCCESS;
  412. end;
  413. function TWasmRegExpAPI.RegExpGetNamedGroup(aExprID: TWasmRegExpID; aName: PByte; aNameLen: Longint; aValue: PByte;
  414. aValueLen: PLongint): TWasmRegexpResult;
  415. var
  416. lRegExp : TWasmRegExp;
  417. lName,S : String;
  418. lOldLen,lLen : Integer;
  419. begin
  420. lName:=Env.GetUTF8StringFromMem(aName,aNameLen);
  421. {$IFNDEF NOLOGAPICALLS}
  422. If LogAPICalls then
  423. LogCall('RegExp.GetNamedGroup(%d,"%s",[%x],[%x])',[aExprID,lName,aValue,aValueLen]);
  424. {$ENDIF}
  425. lRegExp:=FindRegExp(aExprID);
  426. if lRegExp=Nil then
  427. Exit(WASMRE_RESULT_INVALIDID);
  428. S:=lRegExp.GetGroupValue(lName);
  429. lOldLen:=Env.GetMemInfoInt32(aValueLen);
  430. lLen:=Env.SetUTF8StringInMem(aValue,lOldLen,S);
  431. Env.SetMemInfoInt32(aValueLen,abs(lLen));
  432. if lLen<0 then
  433. Exit(WASMRE_RESULT_NO_MEM);
  434. Result:=WASMRE_RESULT_SUCCESS;
  435. end;
  436. function TWasmRegExpAPI.RegExpGetIndexes(aExprID: TWasmRegExpID; aIndex: Longint; aStartIndex: PLongint; aStopIndex: PLongint
  437. ): TWasmRegexpResult;
  438. var
  439. lRegExp : TWasmRegExp;
  440. Indexes : TIndexArray;
  441. begin
  442. {$IFNDEF NOLOGAPICALLS}
  443. If LogAPICalls then
  444. LogCall('RegExp.GetIndexes(%d,%d,[%x],[%x])',[aExprID,aIndex,aStartIndex,AStopIndex]);
  445. {$ENDIF}
  446. lRegExp:=FindRegExp(aExprID);
  447. if lRegExp=Nil then
  448. Exit(WASMRE_RESULT_INVALIDID);
  449. if pos('d',lRegExp.RegExp.Flags)=0 then
  450. Exit(WASMRE_RESULT_NOINDEXES);
  451. if (aIndex<0) or (aIndex>=lRegExp.ResultMatchCount) then
  452. Exit(WASMRE_RESULT_INVALIDIDX);
  453. Indexes:=lRegExp.GetMatchIndexes(aIndex);
  454. Env.SetMemInfoInt32(aStartIndex,Indexes[0]);
  455. Env.SetMemInfoInt32(aStopIndex,Indexes[1]);
  456. Result:=WASMRE_RESULT_SUCCESS;
  457. end;
  458. function TWasmRegExpAPI.RegExpGetNamedGroupIndexes(aExprID: TWasmRegExpID; aName: PByte; aNameLen: Integer; aStartIndex: PLongint;
  459. aStopIndex: PLongint): TWasmRegexpResult;
  460. var
  461. lRegExp : TWasmRegExp;
  462. Indexes : TIndexArray;
  463. lName : String;
  464. begin
  465. lName:=Env.GetUTF8StringFromMem(aName,aNameLen);
  466. {$IFNDEF NOLOGAPICALLS}
  467. If LogAPICalls then
  468. LogCall('RegExp.RegExp.GetIndexes(%d,"%s",[%x],[%x])',[aExprID,lName,aStartIndex,AStopIndex]);
  469. {$ENDIF}
  470. lRegExp:=FindRegExp(aExprID);
  471. if lRegExp=Nil then
  472. Exit(WASMRE_RESULT_INVALIDID);
  473. Indexes:=lRegExp.GetGroupIndexes(lName);
  474. Env.SetMemInfoInt32(aStartIndex,Indexes[0]);
  475. Env.SetMemInfoInt32(aStopIndex,Indexes[1]);
  476. Result:=WASMRE_RESULT_SUCCESS;
  477. end;
  478. constructor TWasmRegExpAPI.Create(aEnv: TPas2JSWASIEnvironment);
  479. begin
  480. inherited Create(aEnv);
  481. FRegExps:=TJSObject.new;
  482. end;
  483. procedure TWasmRegExpAPI.DoError(const Msg: String);
  484. begin
  485. Console.Error(Msg);
  486. end;
  487. procedure TWasmRegExpAPI.DoError(const Fmt: String; const Args: array of const);
  488. begin
  489. Console.Error(Format(Fmt,Args));
  490. end;
  491. procedure TWasmRegExpAPI.LogCall(const Msg: String);
  492. begin
  493. {$IFNDEF NOLOGAPICALLS}
  494. If not LogAPICalls then exit;
  495. Writeln(Msg);
  496. {$ENDIF}
  497. end;
  498. procedure TWasmRegExpAPI.LogCall(const Fmt: String; const Args: array of const);
  499. begin
  500. {$IFNDEF NOLOGAPICALLS}
  501. If not LogAPICalls then exit;
  502. Writeln(Format(Fmt,Args));
  503. {$ENDIF}
  504. end;
  505. function TWasmRegExpAPI.GetNextID: TWasmRegExpID;
  506. begin
  507. Inc(FNextID);
  508. Result:=FNextID;
  509. end;
  510. function TWasmRegExpAPI.FindRegExp(aID: TWasmRegExpID): TWasmRegexp;
  511. var
  512. Value : JSValue;
  513. begin
  514. Value:=FRegExps[IntToStr(aID)];
  515. if isObject(Value) then
  516. Result:=TWasmRegexp(Value)
  517. else
  518. Result:=Nil;
  519. end;
  520. procedure TWasmRegExpAPI.FillImportObject(aObject: TJSObject);
  521. begin
  522. AObject[regexpFN_Allocate]:=@RegExpAllocate;
  523. AObject[regexpFN_DeAllocate]:=@RegExpDeallocate;
  524. AObject[regexpFN_Exec]:=@RegExpExec;
  525. AObject[regexpFN_Test]:=@RegExpTest;
  526. AObject[regexpFN_GetFlags]:=@RegExpGetFlags;
  527. AObject[regexpFN_GetExpression]:=@RegExpGetExpression;
  528. AObject[regexpFN_GetLastIndex]:=@RegExpGetLastIndex;
  529. AObject[regexpFN_GetResultMatch]:=@RegExpGetResultMatch;
  530. AObject[regexpFN_GetGroupCount]:=@RegExpGetGroupCount;
  531. AObject[regexpFN_GetGroupName]:=@RegExpGetGroupName;
  532. AObject[regexpFN_GetNamedGroup]:=@RegExpGetNamedGroup;
  533. AObject[regexpFN_GetIndexes]:=@RegExpGetIndexes;
  534. AObject[regexpFN_GetNamedGroupIndexes]:=@RegExpGetNamedGroupIndexes;
  535. end;
  536. function TWasmRegExpAPI.ImportName: String;
  537. begin
  538. Result:=regexpExportName;
  539. end;
  540. end.