aot_emit_stringref.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #if WASM_ENABLE_STRINGREF != 0
  6. #include "aot_emit_stringref.h"
  7. #include "aot_emit_exception.h"
  8. #include "aot_emit_memory.h"
  9. #include "aot_emit_gc.h"
  10. #include "aot.h"
  11. #include "aot_compiler.h"
  12. #include "aot_emit_memory.h"
  13. #include "gc_object.h"
  14. #include "string_object.h"
  15. #define BUILD_ISNULL(ptr, res, name) \
  16. do { \
  17. if (!(res = LLVMBuildIsNull(comp_ctx->builder, ptr, name))) { \
  18. aot_set_last_error("llvm build isnull failed."); \
  19. goto fail; \
  20. } \
  21. } while (0)
  22. #define BUILD_ISNOTNULL(ptr, res, name) \
  23. do { \
  24. if (!(res = LLVMBuildIsNotNull(comp_ctx->builder, ptr, name))) { \
  25. aot_set_last_error("llvm build isnotnull failed."); \
  26. goto fail; \
  27. } \
  28. } while (0)
  29. #define ADD_BASIC_BLOCK(block, name) \
  30. do { \
  31. if (!(block = LLVMAppendBasicBlockInContext(comp_ctx->context, \
  32. func_ctx->func, name))) { \
  33. aot_set_last_error("llvm add basic block failed."); \
  34. goto fail; \
  35. } \
  36. } while (0)
  37. #define CURR_BLOCK() LLVMGetInsertBlock(comp_ctx->builder)
  38. #define MOVE_BLOCK_AFTER(llvm_block, llvm_block_after) \
  39. LLVMMoveBasicBlockAfter(llvm_block, llvm_block_after)
  40. #define MOVE_BLOCK_AFTER_CURR(llvm_block) \
  41. LLVMMoveBasicBlockAfter(llvm_block, CURR_BLOCK())
  42. #define DEFINE_STRINGREF_CHECK_VAR() \
  43. LLVMBasicBlockRef check_string_obj_succ, check_stringref_obj_succ; \
  44. LLVMValueRef cmp
  45. #define CHECK_STRING_OBJ(str_obj) \
  46. do { \
  47. ADD_BASIC_BLOCK(check_string_obj_succ, "check string obj succ"); \
  48. MOVE_BLOCK_AFTER_CURR(check_string_obj_succ); \
  49. \
  50. BUILD_ISNULL(str_obj, cmp, "cmp_string_obj"); \
  51. if (!aot_emit_exception(comp_ctx, func_ctx, \
  52. EXCE_FAILED_TO_CREATE_STRING, true, cmp, \
  53. check_string_obj_succ)) \
  54. goto fail; \
  55. } while (0)
  56. #define CHECK_STRINGREF_INTERNAL(stringref_obj, exce_id, name) \
  57. do { \
  58. ADD_BASIC_BLOCK(check_stringref_obj_succ, "check " name " obj succ"); \
  59. MOVE_BLOCK_AFTER(check_stringref_obj_succ, check_string_obj_succ); \
  60. \
  61. BUILD_ISNULL(stringref_obj, cmp, "cmp_" name "_obj"); \
  62. if (!aot_emit_exception(comp_ctx, func_ctx, exce_id, true, cmp, \
  63. check_stringref_obj_succ)) \
  64. goto fail; \
  65. } while (0)
  66. #define CHECK_STRINGREF_OBJ(stringref_obj) \
  67. CHECK_STRINGREF_INTERNAL(stringref_obj, EXCE_FAILED_TO_CREATE_STRINGREF, \
  68. "stringref")
  69. #define CHECK_STRINGVIEW_OBJ(stringview_obj) \
  70. CHECK_STRINGREF_INTERNAL(stringview_obj, EXCE_FAILED_TO_CREATE_STRINGVIEW, \
  71. "stringview")
  72. #define CHECK_STRING_ENCODE(value) \
  73. do { \
  74. ADD_BASIC_BLOCK(check_string_encode_succ, "check string encode succ"); \
  75. MOVE_BLOCK_AFTER_CURR(check_string_encode_succ); \
  76. \
  77. if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntSLT, value, \
  78. I32_ZERO, "cmp_string_encode"))) { \
  79. aot_set_last_error("llvm build icmp failed."); \
  80. goto fail; \
  81. } \
  82. \
  83. if (!aot_emit_exception(comp_ctx, func_ctx, \
  84. EXCE_FAILED_TO_ENCODE_STRING, true, cmp, \
  85. check_string_encode_succ)) \
  86. goto fail; \
  87. } while (0)
  88. static bool
  89. aot_call_wasm_stringref_obj_new(AOTCompContext *comp_ctx,
  90. AOTFuncContext *func_ctx, LLVMValueRef str_obj,
  91. uint32 stringref_type, uint32 pos,
  92. LLVMValueRef *stringref_obj)
  93. {
  94. LLVMValueRef param_values[3], func, value, res;
  95. LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
  96. uint32 argc = 2;
  97. param_types[0] = INT8_PTR_TYPE;
  98. param_types[1] = INT8_PTR_TYPE;
  99. param_types[2] = I32_TYPE;
  100. ret_type = INT8_PTR_TYPE;
  101. if (stringref_type == WASM_TYPE_STRINGREF) {
  102. GET_AOT_FUNCTION(wasm_stringref_obj_new, argc);
  103. }
  104. else if (stringref_type == WASM_TYPE_STRINGVIEWWTF8) {
  105. GET_AOT_FUNCTION(wasm_stringview_wtf8_obj_new, argc);
  106. }
  107. else if (stringref_type == WASM_TYPE_STRINGVIEWWTF16) {
  108. GET_AOT_FUNCTION(wasm_stringview_wtf16_obj_new, argc);
  109. }
  110. else {
  111. argc = 3;
  112. GET_AOT_FUNCTION(wasm_stringview_iter_obj_new, argc);
  113. }
  114. param_values[0] = func_ctx->exec_env;
  115. param_values[1] = str_obj;
  116. if (stringref_type == WASM_TYPE_STRINGVIEWITER) {
  117. param_values[2] = I32_CONST(pos);
  118. }
  119. if (!(res = LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values,
  120. argc, "create_stringref"))) {
  121. aot_set_last_error("llvm build call failed.");
  122. goto fail;
  123. }
  124. *stringref_obj = res;
  125. return true;
  126. fail:
  127. return false;
  128. }
  129. static LLVMValueRef
  130. aot_stringref_obj_get_value(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  131. LLVMValueRef stringref_obj)
  132. {
  133. LLVMValueRef str_obj_ptr, str_obj, host_ptr_offset;
  134. /* header */
  135. host_ptr_offset = I32_CONST(comp_ctx->pointer_size);
  136. if (!(stringref_obj =
  137. LLVMBuildBitCast(comp_ctx->builder, stringref_obj, INT8_PTR_TYPE,
  138. "stringref_obj_i8p"))) {
  139. aot_set_last_error("llvm build bitcast failed.");
  140. goto fail;
  141. }
  142. if (!(str_obj_ptr =
  143. LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, stringref_obj,
  144. &host_ptr_offset, 1, "str_obj_i8p"))) {
  145. aot_set_last_error("llvm build gep failed.");
  146. goto fail;
  147. }
  148. if (!(str_obj_ptr = LLVMBuildBitCast(comp_ctx->builder, str_obj_ptr,
  149. GC_REF_PTR_TYPE, "str_obj_gcref_p"))) {
  150. aot_set_last_error("llvm build bitcast failed.");
  151. goto fail;
  152. }
  153. if (!(str_obj = LLVMBuildLoad2(comp_ctx->builder, GC_REF_TYPE, str_obj_ptr,
  154. "str_obj"))) {
  155. aot_set_last_error("llvm build load failed.");
  156. goto fail;
  157. }
  158. LLVMSetAlignment(str_obj, 4);
  159. return str_obj;
  160. fail:
  161. return NULL;
  162. }
  163. static LLVMValueRef
  164. get_stringview_iter_pos_addr(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  165. LLVMValueRef stringview_iter_obj)
  166. {
  167. LLVMValueRef iter_pos_ptr, host_ptr_offset;
  168. /* header + str_obj */
  169. host_ptr_offset = I32_CONST(comp_ctx->pointer_size * 2);
  170. if (!(stringview_iter_obj =
  171. LLVMBuildBitCast(comp_ctx->builder, stringview_iter_obj,
  172. INT8_PTR_TYPE, "stringview_iter_obj_i8p"))) {
  173. aot_set_last_error("llvm build bitcast failed.");
  174. goto fail;
  175. }
  176. if (!(iter_pos_ptr = LLVMBuildInBoundsGEP2(
  177. comp_ctx->builder, INT8_TYPE, stringview_iter_obj,
  178. &host_ptr_offset, 1, "iter_pos_i8p"))) {
  179. aot_set_last_error("llvm build gep failed.");
  180. goto fail;
  181. }
  182. if (!(iter_pos_ptr = LLVMBuildBitCast(comp_ctx->builder, iter_pos_ptr,
  183. INT32_PTR_TYPE, "iter_pos_i32p"))) {
  184. aot_set_last_error("llvm build bitcast failed.");
  185. goto fail;
  186. }
  187. return iter_pos_ptr;
  188. fail:
  189. return NULL;
  190. }
  191. static LLVMValueRef
  192. aot_call_wasm_string_measure(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  193. LLVMValueRef stringref_obj, uint32 encoding)
  194. {
  195. LLVMValueRef param_values[3], func, value, str_obj;
  196. LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
  197. if (!(str_obj =
  198. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  199. goto fail;
  200. }
  201. param_types[0] = INT8_PTR_TYPE;
  202. param_types[1] = I32_TYPE;
  203. ret_type = I32_TYPE;
  204. GET_AOT_FUNCTION(wasm_string_measure, 2);
  205. /* Call function wasm_string_measure() */
  206. param_values[0] = str_obj;
  207. param_values[1] = I32_CONST(encoding);
  208. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  209. param_values, 2, "string_measure"))) {
  210. aot_set_last_error("llvm build call failed.");
  211. goto fail;
  212. }
  213. return value;
  214. fail:
  215. return NULL;
  216. }
  217. static LLVMValueRef
  218. aot_call_wasm_string_create_view(AOTCompContext *comp_ctx,
  219. AOTFuncContext *func_ctx,
  220. LLVMValueRef stringref_obj, uint32 encoding)
  221. {
  222. LLVMValueRef param_values[3], func, value, str_obj;
  223. LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
  224. if (!(str_obj =
  225. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  226. goto fail;
  227. }
  228. param_types[0] = INT8_PTR_TYPE;
  229. param_types[1] = I32_TYPE;
  230. ret_type = INT8_PTR_TYPE;
  231. GET_AOT_FUNCTION(wasm_string_create_view, 2);
  232. /* Call function wasm_string_create_view() */
  233. param_values[0] = str_obj;
  234. param_values[1] = I32_CONST(encoding);
  235. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  236. param_values, 2, "string_create_view"))) {
  237. aot_set_last_error("llvm build call failed.");
  238. goto fail;
  239. }
  240. return value;
  241. fail:
  242. return NULL;
  243. }
  244. static LLVMValueRef
  245. aot_call_wasm_string_advance(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  246. LLVMValueRef stringref_obj, LLVMValueRef bytes,
  247. LLVMValueRef pos)
  248. {
  249. LLVMValueRef param_values[4], func, value, str_obj;
  250. LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
  251. if (!(str_obj =
  252. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  253. goto fail;
  254. }
  255. param_types[0] = INT8_PTR_TYPE;
  256. param_types[1] = I32_TYPE;
  257. param_types[2] = I32_TYPE;
  258. param_types[3] = INT32_PTR_TYPE;
  259. ret_type = INT8_PTR_TYPE;
  260. GET_AOT_FUNCTION(wasm_string_advance, 4);
  261. /* Call function wasm_string_advance() */
  262. param_values[0] = str_obj;
  263. param_values[1] = pos;
  264. param_values[2] = bytes;
  265. param_values[3] = I8_PTR_NULL;
  266. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  267. param_values, 4, "string_advance"))) {
  268. aot_set_last_error("llvm build call failed.");
  269. goto fail;
  270. }
  271. return value;
  272. fail:
  273. return NULL;
  274. }
  275. static LLVMValueRef
  276. aot_call_wasm_string_slice(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  277. LLVMValueRef stringref_obj, LLVMValueRef start,
  278. LLVMValueRef end, StringViewType stringview_type)
  279. {
  280. LLVMValueRef param_values[4], func, value, str_obj;
  281. LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
  282. if (!(str_obj =
  283. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  284. goto fail;
  285. }
  286. param_types[0] = INT8_PTR_TYPE;
  287. param_types[1] = I32_TYPE;
  288. param_types[2] = I32_TYPE;
  289. param_types[3] = I32_TYPE;
  290. ret_type = INT8_PTR_TYPE;
  291. GET_AOT_FUNCTION(wasm_string_slice, 4);
  292. /* Call function wasm_string_slice() */
  293. param_values[0] = str_obj;
  294. param_values[1] = start;
  295. param_values[2] = end;
  296. param_values[3] = I32_CONST(stringview_type);
  297. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  298. param_values, 4, "string_slice"))) {
  299. aot_set_last_error("llvm build call failed.");
  300. goto fail;
  301. }
  302. return value;
  303. fail:
  304. return NULL;
  305. }
  306. bool
  307. aot_compile_op_string_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  308. uint32 encoding)
  309. {
  310. LLVMValueRef maddr, byte_length, offset, str_obj, stringref_obj;
  311. LLVMValueRef param_values[5], func, value;
  312. LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;
  313. DEFINE_STRINGREF_CHECK_VAR();
  314. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  315. return false;
  316. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  317. return false;
  318. POP_I32(byte_length);
  319. POP_I32(offset);
  320. if (!(maddr = check_bulk_memory_overflow(comp_ctx, func_ctx, offset,
  321. byte_length)))
  322. goto fail;
  323. param_types[0] = INT8_PTR_TYPE;
  324. param_types[1] = I32_TYPE;
  325. param_types[2] = I32_TYPE;
  326. ret_type = INT8_PTR_TYPE;
  327. GET_AOT_FUNCTION(wasm_string_new_with_encoding, 3);
  328. /* Call function wasm_struct_obj_new() */
  329. param_values[0] = maddr;
  330. param_values[1] = byte_length;
  331. param_values[2] = I32_CONST(encoding);
  332. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  333. param_values, 3, "wasm_string_new"))) {
  334. aot_set_last_error("llvm build call failed.");
  335. goto fail;
  336. }
  337. CHECK_STRING_OBJ(str_obj);
  338. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  339. WASM_TYPE_STRINGREF, 0,
  340. &stringref_obj)) {
  341. goto fail;
  342. }
  343. CHECK_STRINGREF_OBJ(stringref_obj);
  344. PUSH_GC_REF(stringref_obj);
  345. return true;
  346. fail:
  347. return false;
  348. }
  349. bool
  350. aot_compile_op_string_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  351. uint32 contents)
  352. {
  353. LLVMValueRef param_values[2], func, value, str_obj, stringref_obj;
  354. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  355. DEFINE_STRINGREF_CHECK_VAR();
  356. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  357. return false;
  358. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  359. return false;
  360. param_types[0] = INT8_PTR_TYPE;
  361. param_types[1] = I32_TYPE;
  362. ret_type = INT8_PTR_TYPE;
  363. GET_AOT_FUNCTION(wasm_string_new_const, 2);
  364. bh_assert(contents < comp_ctx->comp_data->string_literal_count);
  365. param_values[0] = LLVMConstIntToPtr(
  366. I64_CONST((unsigned long long)(uintptr_t)
  367. comp_ctx->comp_data->string_literal_ptrs_wp[contents]),
  368. INT8_PTR_TYPE);
  369. param_values[1] =
  370. I32_CONST(comp_ctx->comp_data->string_literal_lengths_wp[contents]);
  371. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  372. param_values, 2, "create_stringref"))) {
  373. aot_set_last_error("llvm build call failed.");
  374. goto fail;
  375. }
  376. CHECK_STRING_OBJ(str_obj);
  377. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  378. WASM_TYPE_STRINGREF, 0,
  379. &stringref_obj)) {
  380. goto fail;
  381. }
  382. CHECK_STRINGREF_OBJ(stringref_obj);
  383. PUSH_GC_REF(stringref_obj);
  384. return true;
  385. fail:
  386. return false;
  387. }
  388. bool
  389. aot_compile_op_string_measure(AOTCompContext *comp_ctx,
  390. AOTFuncContext *func_ctx, uint32 encoding)
  391. {
  392. LLVMValueRef stringref_obj, value;
  393. POP_GC_REF(stringref_obj);
  394. if (!(value = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  395. stringref_obj, encoding))) {
  396. goto fail;
  397. }
  398. PUSH_I32(value);
  399. return true;
  400. fail:
  401. return false;
  402. }
  403. bool
  404. aot_compile_op_string_encode(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  405. uint32 mem_idx, uint32 encoding)
  406. {
  407. LLVMValueRef param_values[6], func, value, offset, length, maddr, str_obj,
  408. stringref_obj;
  409. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  410. LLVMBasicBlockRef check_string_encode_succ;
  411. LLVMValueRef cmp;
  412. POP_I32(offset);
  413. POP_GC_REF(stringref_obj);
  414. if (!(str_obj =
  415. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  416. goto fail;
  417. }
  418. if (!(length = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  419. stringref_obj, encoding))) {
  420. goto fail;
  421. }
  422. if (!(maddr =
  423. check_bulk_memory_overflow(comp_ctx, func_ctx, offset, length)))
  424. goto fail;
  425. param_types[0] = INT8_PTR_TYPE;
  426. param_types[1] = I32_TYPE;
  427. param_types[2] = I32_TYPE;
  428. param_types[3] = INT8_PTR_TYPE;
  429. param_types[4] = INT8_PTR_TYPE;
  430. param_types[5] = I32_TYPE;
  431. ret_type = I32_TYPE;
  432. GET_AOT_FUNCTION(wasm_string_encode, 6);
  433. /* Call function wasm_string_measure() */
  434. param_values[0] = str_obj;
  435. param_values[1] = I32_ZERO;
  436. param_values[2] = length;
  437. param_values[3] = maddr;
  438. param_values[4] = I8_PTR_NULL;
  439. param_values[5] = I32_CONST(encoding);
  440. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  441. param_values, 6, "string_encode"))) {
  442. aot_set_last_error("llvm build call failed.");
  443. goto fail;
  444. }
  445. CHECK_STRING_ENCODE(value);
  446. PUSH_I32(value);
  447. return true;
  448. fail:
  449. return false;
  450. }
  451. bool
  452. aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  453. {
  454. LLVMValueRef param_values[2], func, value, str_obj_lhs, str_obj_rhs,
  455. stringref_obj_lhs, stringref_obj_rhs, stringref_obj_new;
  456. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  457. DEFINE_STRINGREF_CHECK_VAR();
  458. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  459. return false;
  460. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  461. return false;
  462. POP_GC_REF(stringref_obj_rhs);
  463. POP_GC_REF(stringref_obj_lhs);
  464. if (!(str_obj_lhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  465. stringref_obj_lhs))) {
  466. goto fail;
  467. }
  468. if (!(str_obj_rhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  469. stringref_obj_rhs))) {
  470. goto fail;
  471. }
  472. param_types[0] = INT8_PTR_TYPE;
  473. param_types[1] = INT8_PTR_TYPE;
  474. ret_type = INT8_PTR_TYPE;
  475. GET_AOT_FUNCTION(wasm_string_concat, 2);
  476. /* Call function wasm_string_concat() */
  477. param_values[0] = str_obj_lhs;
  478. param_values[1] = str_obj_rhs;
  479. if (!(str_obj_lhs = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  480. param_values, 2, "string_concat"))) {
  481. aot_set_last_error("llvm build call failed.");
  482. goto fail;
  483. }
  484. CHECK_STRING_OBJ(str_obj_lhs);
  485. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj_lhs,
  486. WASM_TYPE_STRINGREF, 0,
  487. &stringref_obj_new)) {
  488. goto fail;
  489. }
  490. CHECK_STRINGREF_OBJ(stringref_obj_new);
  491. PUSH_GC_REF(stringref_obj_new);
  492. return true;
  493. fail:
  494. return false;
  495. }
  496. bool
  497. aot_compile_op_string_eq(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  498. {
  499. LLVMValueRef param_values[2], func, value, str_obj_lhs, str_obj_rhs,
  500. stringref_obj_lhs, stringref_obj_rhs;
  501. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  502. POP_GC_REF(stringref_obj_lhs);
  503. POP_GC_REF(stringref_obj_rhs);
  504. if (!(str_obj_lhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  505. stringref_obj_lhs))) {
  506. goto fail;
  507. }
  508. if (!(str_obj_rhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  509. stringref_obj_rhs))) {
  510. goto fail;
  511. }
  512. param_types[0] = INT8_PTR_TYPE;
  513. param_types[1] = INT8_PTR_TYPE;
  514. ret_type = I32_TYPE;
  515. GET_AOT_FUNCTION(wasm_string_eq, 2);
  516. /* Call function wasm_string_eq() */
  517. param_values[0] = str_obj_lhs;
  518. param_values[1] = str_obj_rhs;
  519. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  520. param_values, 2, "string_eq"))) {
  521. aot_set_last_error("llvm build call failed.");
  522. goto fail;
  523. }
  524. PUSH_I32(value);
  525. return true;
  526. fail:
  527. return false;
  528. }
  529. bool
  530. aot_compile_op_string_is_usv_sequence(AOTCompContext *comp_ctx,
  531. AOTFuncContext *func_ctx)
  532. {
  533. LLVMValueRef param_values[1], func, value, str_obj, stringref_obj;
  534. LLVMTypeRef param_types[1], ret_type, func_type, func_ptr_type;
  535. POP_GC_REF(stringref_obj);
  536. if (!(str_obj =
  537. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  538. goto fail;
  539. }
  540. param_types[0] = INT8_PTR_TYPE;
  541. ret_type = I32_TYPE;
  542. GET_AOT_FUNCTION(wasm_string_is_usv_sequence, 1);
  543. /* Call function wasm_string_is_usv_sequence() */
  544. param_values[0] = str_obj;
  545. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  546. param_values, 1, "string_is_usv_sequence"))) {
  547. aot_set_last_error("llvm build call failed.");
  548. goto fail;
  549. }
  550. PUSH_I32(value);
  551. return true;
  552. fail:
  553. return false;
  554. }
  555. bool
  556. aot_compile_op_string_as_wtf8(AOTCompContext *comp_ctx,
  557. AOTFuncContext *func_ctx)
  558. {
  559. LLVMValueRef str_obj, stringref_obj, stringview_wtf8_obj;
  560. DEFINE_STRINGREF_CHECK_VAR();
  561. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  562. return false;
  563. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  564. return false;
  565. POP_GC_REF(stringref_obj);
  566. if (!(str_obj = aot_call_wasm_string_create_view(
  567. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF8))) {
  568. goto fail;
  569. }
  570. CHECK_STRING_OBJ(str_obj);
  571. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  572. WASM_TYPE_STRINGVIEWWTF8, 0,
  573. &stringview_wtf8_obj)) {
  574. goto fail;
  575. }
  576. CHECK_STRINGVIEW_OBJ(stringref_obj);
  577. PUSH_GC_REF(stringview_wtf8_obj);
  578. return true;
  579. fail:
  580. return false;
  581. }
  582. bool
  583. aot_compile_op_stringview_wtf8_advance(AOTCompContext *comp_ctx,
  584. AOTFuncContext *func_ctx)
  585. {
  586. LLVMValueRef stringref_obj, bytes, pos, value;
  587. POP_I32(bytes);
  588. POP_I32(pos);
  589. POP_GC_REF(stringref_obj);
  590. if (!(value = aot_call_wasm_string_advance(comp_ctx, func_ctx,
  591. stringref_obj, bytes, pos))) {
  592. goto fail;
  593. }
  594. PUSH_I32(value);
  595. return true;
  596. fail:
  597. return false;
  598. }
  599. bool
  600. aot_compile_op_stringview_wtf8_encode(AOTCompContext *comp_ctx,
  601. AOTFuncContext *func_ctx, uint32 mem_idx,
  602. uint32 encoding)
  603. {
  604. LLVMValueRef param_values[6], func, value, offset, maddr, str_obj,
  605. stringref_obj;
  606. LLVMValueRef bytes, pos, next_pos;
  607. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  608. LLVMBasicBlockRef check_string_encode_succ;
  609. LLVMValueRef cmp;
  610. POP_I32(bytes);
  611. POP_I32(pos);
  612. POP_I32(offset);
  613. next_pos = LLVMBuildAlloca(comp_ctx->builder, I32_TYPE, "next_pos");
  614. if (!next_pos) {
  615. aot_set_last_error("failed to build alloca");
  616. goto fail;
  617. }
  618. if (!(maddr =
  619. check_bulk_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
  620. goto fail;
  621. POP_GC_REF(stringref_obj);
  622. if (!(str_obj =
  623. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  624. goto fail;
  625. }
  626. param_types[0] = INT8_PTR_TYPE;
  627. param_types[1] = I32_TYPE;
  628. param_types[2] = I32_TYPE;
  629. param_types[3] = INT8_PTR_TYPE;
  630. param_types[4] = INT8_PTR_TYPE;
  631. param_types[5] = I32_TYPE;
  632. ret_type = I32_TYPE;
  633. GET_AOT_FUNCTION(wasm_string_encode, 6);
  634. /* Call function wasm_string_measure() */
  635. param_values[0] = str_obj;
  636. param_values[1] = pos;
  637. param_values[2] = bytes;
  638. param_values[3] = maddr;
  639. param_values[4] = next_pos;
  640. param_values[5] = I32_CONST(encoding);
  641. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  642. param_values, 6, "string_encode"))) {
  643. aot_set_last_error("llvm build call failed.");
  644. goto fail;
  645. }
  646. CHECK_STRING_ENCODE(value);
  647. next_pos =
  648. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, next_pos, "next_pos");
  649. if (!next_pos) {
  650. aot_set_last_error("llvm build load failed.");
  651. goto fail;
  652. }
  653. LLVMSetAlignment(next_pos, 4);
  654. PUSH_I32(next_pos);
  655. PUSH_I32(value);
  656. return true;
  657. fail:
  658. return false;
  659. }
  660. bool
  661. aot_compile_op_stringview_wtf8_slice(AOTCompContext *comp_ctx,
  662. AOTFuncContext *func_ctx)
  663. {
  664. LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
  665. DEFINE_STRINGREF_CHECK_VAR();
  666. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  667. return false;
  668. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  669. return false;
  670. POP_I32(start);
  671. POP_I32(end);
  672. POP_GC_REF(stringref_obj);
  673. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx, stringref_obj,
  674. start, end, STRING_VIEW_WTF8))) {
  675. goto fail;
  676. }
  677. CHECK_STRING_OBJ(value);
  678. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  679. WASM_TYPE_STRINGREF, 0,
  680. &stringref_obj_new)) {
  681. goto fail;
  682. }
  683. CHECK_STRINGREF_OBJ(stringref_obj_new);
  684. PUSH_GC_REF(stringref_obj_new);
  685. return true;
  686. fail:
  687. return false;
  688. }
  689. bool
  690. aot_compile_op_string_as_wtf16(AOTCompContext *comp_ctx,
  691. AOTFuncContext *func_ctx)
  692. {
  693. LLVMValueRef str_obj, stringref_obj, stringview_wtf16_obj;
  694. DEFINE_STRINGREF_CHECK_VAR();
  695. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  696. return false;
  697. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  698. return false;
  699. POP_GC_REF(stringref_obj);
  700. if (!(str_obj = aot_call_wasm_string_create_view(
  701. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF16))) {
  702. goto fail;
  703. }
  704. CHECK_STRING_OBJ(str_obj);
  705. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  706. WASM_TYPE_STRINGVIEWWTF16, 0,
  707. &stringview_wtf16_obj)) {
  708. goto fail;
  709. }
  710. CHECK_STRINGVIEW_OBJ(stringview_wtf16_obj);
  711. PUSH_GC_REF(stringview_wtf16_obj);
  712. return true;
  713. fail:
  714. return false;
  715. }
  716. bool
  717. aot_compile_op_stringview_wtf16_length(AOTCompContext *comp_ctx,
  718. AOTFuncContext *func_ctx)
  719. {
  720. LLVMValueRef param_values[2], func, value, str_obj, stringview_wtf16_obj;
  721. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  722. POP_GC_REF(stringview_wtf16_obj);
  723. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  724. stringview_wtf16_obj))) {
  725. goto fail;
  726. }
  727. param_types[0] = INT8_PTR_TYPE;
  728. ret_type = I32_TYPE;
  729. GET_AOT_FUNCTION(wasm_string_wtf16_get_length, 6);
  730. /* Call function wasm_string_wtf16_get_length() */
  731. param_values[0] = str_obj;
  732. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  733. param_values, 1, "stringview_wtf16_length"))) {
  734. aot_set_last_error("llvm build call failed.");
  735. goto fail;
  736. }
  737. PUSH_I32(value);
  738. return true;
  739. fail:
  740. return false;
  741. }
  742. bool
  743. aot_compile_op_stringview_wtf16_get_codeunit(AOTCompContext *comp_ctx,
  744. AOTFuncContext *func_ctx)
  745. {
  746. LLVMValueRef param_values[2], func, value, str_obj, stringview_wtf16_obj,
  747. pos;
  748. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  749. POP_I32(pos);
  750. POP_GC_REF(stringview_wtf16_obj);
  751. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  752. stringview_wtf16_obj))) {
  753. goto fail;
  754. }
  755. param_types[0] = INT8_PTR_TYPE;
  756. param_types[1] = I32_TYPE;
  757. ret_type = I32_TYPE;
  758. GET_AOT_FUNCTION(wasm_string_get_wtf16_codeunit, 2);
  759. /* Call function wasm_string_get_wtf16_codeunit() */
  760. param_values[0] = str_obj;
  761. param_values[1] = pos;
  762. if (!(value =
  763. LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values,
  764. 2, "stringview_wtf16_get_codeunit"))) {
  765. aot_set_last_error("llvm build call failed.");
  766. goto fail;
  767. }
  768. PUSH_I32(value);
  769. return true;
  770. fail:
  771. return false;
  772. }
  773. bool
  774. aot_compile_op_stringview_wtf16_encode(AOTCompContext *comp_ctx,
  775. AOTFuncContext *func_ctx, uint32 mem_idx)
  776. {
  777. LLVMValueRef param_values[6], func, value, offset, maddr, str_obj,
  778. stringref_obj;
  779. LLVMValueRef len, pos;
  780. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  781. LLVMBasicBlockRef check_string_encode_succ;
  782. LLVMValueRef cmp;
  783. POP_I32(len);
  784. POP_I32(pos);
  785. POP_I32(offset);
  786. if (!(maddr = check_bulk_memory_overflow(
  787. comp_ctx, func_ctx, offset,
  788. LLVMBuildMul(comp_ctx->builder, len, I32_CONST(2), "wtf16_len"))))
  789. goto fail;
  790. POP_GC_REF(stringref_obj);
  791. if (!check_memory_alignment(comp_ctx, func_ctx, maddr, 2)) {
  792. goto fail;
  793. }
  794. if (!(str_obj =
  795. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  796. goto fail;
  797. }
  798. param_types[0] = INT8_PTR_TYPE;
  799. param_types[1] = I32_TYPE;
  800. param_types[2] = I32_TYPE;
  801. param_types[3] = INT8_PTR_TYPE;
  802. param_types[4] = INT8_PTR_TYPE;
  803. param_types[5] = I32_TYPE;
  804. ret_type = I32_TYPE;
  805. GET_AOT_FUNCTION(wasm_string_encode, 6);
  806. /* Call function wasm_string_measure() */
  807. param_values[0] = str_obj;
  808. param_values[1] = pos;
  809. param_values[2] = len;
  810. param_values[3] = maddr;
  811. param_values[4] = I8_PTR_NULL;
  812. param_values[5] = I32_CONST(WTF16);
  813. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  814. param_values, 6, "string_encode"))) {
  815. aot_set_last_error("llvm build call failed.");
  816. goto fail;
  817. }
  818. CHECK_STRING_ENCODE(value);
  819. PUSH_I32(value);
  820. return true;
  821. fail:
  822. return false;
  823. }
  824. bool
  825. aot_compile_op_stringview_wtf16_slice(AOTCompContext *comp_ctx,
  826. AOTFuncContext *func_ctx)
  827. {
  828. LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
  829. DEFINE_STRINGREF_CHECK_VAR();
  830. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  831. return false;
  832. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  833. return false;
  834. POP_I32(end);
  835. POP_I32(start);
  836. POP_GC_REF(stringref_obj);
  837. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx, stringref_obj,
  838. start, end, STRING_VIEW_WTF16))) {
  839. goto fail;
  840. }
  841. CHECK_STRING_OBJ(value);
  842. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  843. WASM_TYPE_STRINGREF, 0,
  844. &stringref_obj_new)) {
  845. goto fail;
  846. }
  847. CHECK_STRINGREF_OBJ(stringref_obj_new);
  848. PUSH_GC_REF(stringref_obj_new);
  849. return true;
  850. fail:
  851. return false;
  852. }
  853. bool
  854. aot_compile_op_string_as_iter(AOTCompContext *comp_ctx,
  855. AOTFuncContext *func_ctx)
  856. {
  857. LLVMValueRef stringref_obj, stringview_iter_obj, str_obj;
  858. DEFINE_STRINGREF_CHECK_VAR();
  859. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  860. return false;
  861. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  862. return false;
  863. POP_GC_REF(stringref_obj);
  864. if (!(str_obj = aot_call_wasm_string_create_view(
  865. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF8))) {
  866. goto fail;
  867. }
  868. CHECK_STRING_OBJ(str_obj);
  869. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, stringref_obj,
  870. WASM_TYPE_STRINGVIEWITER, 0,
  871. &stringview_iter_obj)) {
  872. goto fail;
  873. }
  874. CHECK_STRINGVIEW_OBJ(stringview_iter_obj);
  875. PUSH_GC_REF(stringview_iter_obj);
  876. return true;
  877. fail:
  878. return false;
  879. }
  880. bool
  881. aot_compile_op_stringview_iter_next(AOTCompContext *comp_ctx,
  882. AOTFuncContext *func_ctx)
  883. {
  884. LLVMValueRef param_values[2], func, value, stringview_iter_obj, str_obj,
  885. iter_pos_addr, pos;
  886. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  887. POP_GC_REF(stringview_iter_obj);
  888. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  889. stringview_iter_obj))) {
  890. goto fail;
  891. }
  892. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  893. stringview_iter_obj))) {
  894. goto fail;
  895. }
  896. pos = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  897. "get_iter_pos");
  898. LLVMSetAlignment(pos, 4);
  899. param_types[0] = INT8_PTR_TYPE;
  900. param_types[1] = I32_TYPE;
  901. ret_type = I32_TYPE;
  902. GET_AOT_FUNCTION(wasm_string_next_codepoint, 2);
  903. /* Call function wasm_string_measure() */
  904. param_values[0] = str_obj;
  905. param_values[1] = pos;
  906. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  907. param_values, 2, "stringview_iter_next"))) {
  908. aot_set_last_error("llvm build call failed.");
  909. goto fail;
  910. }
  911. PUSH_I32(value);
  912. return true;
  913. fail:
  914. return false;
  915. }
  916. static bool
  917. stringview_iter_advance_or_rewind(AOTCompContext *comp_ctx,
  918. AOTFuncContext *func_ctx, bool is_rewind)
  919. {
  920. LLVMValueRef param_values[4], func, value, stringview_iter_obj, str_obj,
  921. code_points_consumed, iter_pos_addr, pos, code_points_count, res;
  922. LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
  923. POP_I32(code_points_count);
  924. POP_GC_REF(stringview_iter_obj);
  925. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  926. stringview_iter_obj))) {
  927. goto fail;
  928. }
  929. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  930. stringview_iter_obj))) {
  931. goto fail;
  932. }
  933. if (!(pos = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  934. "get_iter_pos"))) {
  935. goto fail;
  936. }
  937. LLVMSetAlignment(pos, 4);
  938. if (!(code_points_consumed = LLVMBuildAlloca(comp_ctx->builder, I32_TYPE,
  939. "code_points_consumed"))) {
  940. goto fail;
  941. }
  942. param_types[0] = INT8_PTR_TYPE;
  943. param_types[1] = I32_TYPE;
  944. param_types[2] = I32_TYPE;
  945. param_types[3] = INT32_PTR_TYPE;
  946. ret_type = I32_TYPE;
  947. if (is_rewind) {
  948. GET_AOT_FUNCTION(wasm_string_rewind, 4);
  949. }
  950. else {
  951. GET_AOT_FUNCTION(wasm_string_advance, 4);
  952. }
  953. /* Call function wasm_string_advance() */
  954. param_values[0] = str_obj;
  955. param_values[1] = pos;
  956. param_values[2] = code_points_count;
  957. param_values[3] = code_points_consumed;
  958. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  959. param_values, 4, "string_advance"))) {
  960. aot_set_last_error("llvm build call failed.");
  961. goto fail;
  962. }
  963. if (!(code_points_consumed =
  964. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, code_points_consumed,
  965. "get_code_points_consumed"))) {
  966. aot_set_last_error("llvm build load failed.");
  967. goto fail;
  968. }
  969. LLVMSetAlignment(code_points_consumed, 4);
  970. if (!(res = LLVMBuildStore(comp_ctx->builder, code_points_consumed,
  971. iter_pos_addr))) {
  972. aot_set_last_error("llvm build store failed.");
  973. goto fail;
  974. }
  975. LLVMSetAlignment(res, 4);
  976. PUSH_I32(code_points_consumed);
  977. fail:
  978. return false;
  979. }
  980. bool
  981. aot_compile_op_stringview_iter_advance(AOTCompContext *comp_ctx,
  982. AOTFuncContext *func_ctx)
  983. {
  984. return stringview_iter_advance_or_rewind(comp_ctx, func_ctx, false);
  985. }
  986. bool
  987. aot_compile_op_stringview_iter_rewind(AOTCompContext *comp_ctx,
  988. AOTFuncContext *func_ctx)
  989. {
  990. return stringview_iter_advance_or_rewind(comp_ctx, func_ctx, true);
  991. }
  992. bool
  993. aot_compile_op_stringview_iter_slice(AOTCompContext *comp_ctx,
  994. AOTFuncContext *func_ctx)
  995. {
  996. LLVMValueRef stringview_iter_obj, start, end, stringref_obj_new, value,
  997. iter_pos_addr, code_points_count;
  998. DEFINE_STRINGREF_CHECK_VAR();
  999. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  1000. return false;
  1001. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  1002. return false;
  1003. POP_I32(code_points_count);
  1004. POP_GC_REF(stringview_iter_obj);
  1005. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  1006. stringview_iter_obj))) {
  1007. goto fail;
  1008. }
  1009. if (!(start = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  1010. "get_iter_pos"))) {
  1011. goto fail;
  1012. }
  1013. LLVMSetAlignment(start, 4);
  1014. if (!(end = LLVMBuildAdd(comp_ctx->builder, start, code_points_count,
  1015. "calc_slice_end"))) {
  1016. goto fail;
  1017. }
  1018. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx,
  1019. stringview_iter_obj, start, end,
  1020. STRING_VIEW_ITER))) {
  1021. goto fail;
  1022. }
  1023. CHECK_STRING_OBJ(value);
  1024. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  1025. WASM_TYPE_STRINGREF, 0,
  1026. &stringref_obj_new)) {
  1027. goto fail;
  1028. }
  1029. CHECK_STRINGREF_OBJ(stringref_obj_new);
  1030. PUSH_GC_REF(stringref_obj_new);
  1031. return true;
  1032. fail:
  1033. return false;
  1034. }
  1035. bool
  1036. aot_compile_op_string_new_array(AOTCompContext *comp_ctx,
  1037. AOTFuncContext *func_ctx, uint32 encoding)
  1038. {
  1039. LLVMValueRef start, end, count, str_obj, stringref_obj, array_obj,
  1040. elem_data_ptr;
  1041. LLVMValueRef param_values[5], func, value;
  1042. LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;
  1043. DEFINE_STRINGREF_CHECK_VAR();
  1044. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  1045. return false;
  1046. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
  1047. return false;
  1048. POP_I32(end);
  1049. POP_I32(start);
  1050. POP_GC_REF(array_obj);
  1051. if (!aot_array_obj_elem_addr(
  1052. comp_ctx, func_ctx, array_obj, start, &elem_data_ptr,
  1053. encoding == WTF16 ? PACKED_TYPE_I16 : PACKED_TYPE_I8)) {
  1054. goto fail;
  1055. }
  1056. if (!(count = LLVMBuildSub(comp_ctx->builder, end, start, "calc_count"))) {
  1057. goto fail;
  1058. }
  1059. param_types[0] = INT8_PTR_TYPE;
  1060. param_types[1] = I32_TYPE;
  1061. param_types[2] = I32_TYPE;
  1062. ret_type = INT8_PTR_TYPE;
  1063. GET_AOT_FUNCTION(wasm_string_new_with_encoding, 3);
  1064. /* Call function wasm_struct_obj_new() */
  1065. param_values[0] = elem_data_ptr;
  1066. param_values[1] = count;
  1067. param_values[2] = I32_CONST(encoding);
  1068. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  1069. param_values, 3, "wasm_string_new"))) {
  1070. aot_set_last_error("llvm build call failed.");
  1071. goto fail;
  1072. }
  1073. CHECK_STRING_OBJ(str_obj);
  1074. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  1075. WASM_TYPE_STRINGREF, 0,
  1076. &stringref_obj)) {
  1077. goto fail;
  1078. }
  1079. CHECK_STRINGREF_OBJ(stringref_obj);
  1080. PUSH_GC_REF(stringref_obj);
  1081. return true;
  1082. fail:
  1083. return false;
  1084. }
  1085. bool
  1086. aot_compile_op_string_encode_array(AOTCompContext *comp_ctx,
  1087. AOTFuncContext *func_ctx, uint32 encoding)
  1088. {
  1089. LLVMValueRef param_values[6], func, value, count, start, str_obj,
  1090. stringref_obj, array_obj, elem_data_ptr, array_len;
  1091. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  1092. LLVMBasicBlockRef check_string_encode_succ, check_array_index_succ;
  1093. LLVMValueRef cmp;
  1094. POP_I32(start);
  1095. POP_GC_REF(array_obj);
  1096. POP_GC_REF(stringref_obj);
  1097. if (!(str_obj =
  1098. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  1099. goto fail;
  1100. }
  1101. if (!aot_array_obj_length(comp_ctx, array_obj, &array_len))
  1102. goto fail;
  1103. if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, start, array_len,
  1104. "check_array_index"))) {
  1105. aot_set_last_error("llvm build icmp failed.");
  1106. goto fail;
  1107. }
  1108. ADD_BASIC_BLOCK(check_array_index_succ, "check array index succ");
  1109. MOVE_BLOCK_AFTER_CURR(check_array_index_succ);
  1110. if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_ARRAY_IDX_OOB, true, cmp,
  1111. check_array_index_succ)) {
  1112. goto fail;
  1113. }
  1114. if (!aot_array_obj_elem_addr(
  1115. comp_ctx, func_ctx, stringref_obj, start, &elem_data_ptr,
  1116. encoding == WTF16 ? PACKED_TYPE_I16 : PACKED_TYPE_I8)) {
  1117. goto fail;
  1118. }
  1119. if (!(count = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  1120. stringref_obj, encoding))) {
  1121. goto fail;
  1122. }
  1123. param_types[0] = INT8_PTR_TYPE;
  1124. param_types[1] = I32_TYPE;
  1125. param_types[2] = I32_TYPE;
  1126. param_types[3] = INT8_PTR_TYPE;
  1127. param_types[4] = INT8_PTR_TYPE;
  1128. param_types[5] = I32_TYPE;
  1129. ret_type = I32_TYPE;
  1130. GET_AOT_FUNCTION(wasm_string_encode, 6);
  1131. /* Call function wasm_string_measure() */
  1132. param_values[0] = str_obj;
  1133. param_values[1] = start;
  1134. param_values[2] = count;
  1135. param_values[3] = elem_data_ptr;
  1136. param_values[4] = I8_PTR_NULL;
  1137. param_values[5] = I32_CONST(encoding);
  1138. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  1139. param_values, 6, "string_encode"))) {
  1140. aot_set_last_error("llvm build call failed.");
  1141. goto fail;
  1142. }
  1143. CHECK_STRING_ENCODE(value);
  1144. PUSH_I32(value);
  1145. return true;
  1146. fail:
  1147. return false;
  1148. }
  1149. #endif /* WASM_ENABLE_STRINGREF != 0 */