aot_emit_stringref.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461
  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, const uint8 *frame_ip_stringref_new)
  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, comp_ctx->aot_frame->sp,
  317. frame_ip_stringref_new))
  318. return false;
  319. POP_I32(byte_length);
  320. POP_I32(offset);
  321. if (!(maddr = check_bulk_memory_overflow(comp_ctx, func_ctx, offset,
  322. byte_length)))
  323. goto fail;
  324. param_types[0] = INT8_PTR_TYPE;
  325. param_types[1] = I32_TYPE;
  326. param_types[2] = I32_TYPE;
  327. ret_type = INT8_PTR_TYPE;
  328. GET_AOT_FUNCTION(wasm_string_new_with_encoding, 3);
  329. /* Call function wasm_struct_obj_new() */
  330. param_values[0] = maddr;
  331. param_values[1] = byte_length;
  332. param_values[2] = I32_CONST(encoding);
  333. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  334. param_values, 3, "wasm_string_new"))) {
  335. aot_set_last_error("llvm build call failed.");
  336. goto fail;
  337. }
  338. CHECK_STRING_OBJ(str_obj);
  339. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  340. WASM_TYPE_STRINGREF, 0,
  341. &stringref_obj)) {
  342. goto fail;
  343. }
  344. CHECK_STRINGREF_OBJ(stringref_obj);
  345. PUSH_GC_REF(stringref_obj);
  346. return true;
  347. fail:
  348. return false;
  349. }
  350. bool
  351. aot_compile_op_string_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  352. uint32 contents, const uint8 *frame_ip_string_const)
  353. {
  354. LLVMValueRef param_values[2], func, value, str_obj, stringref_obj;
  355. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  356. DEFINE_STRINGREF_CHECK_VAR();
  357. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  358. return false;
  359. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  360. frame_ip_string_const))
  361. return false;
  362. param_types[0] = INT8_PTR_TYPE;
  363. param_types[1] = I32_TYPE;
  364. ret_type = INT8_PTR_TYPE;
  365. GET_AOT_FUNCTION(wasm_string_new_const, 2);
  366. bh_assert(contents < comp_ctx->comp_data->string_literal_count);
  367. param_values[0] = LLVMConstIntToPtr(
  368. I64_CONST((unsigned long long)(uintptr_t)
  369. comp_ctx->comp_data->string_literal_ptrs_wp[contents]),
  370. INT8_PTR_TYPE);
  371. param_values[1] =
  372. I32_CONST(comp_ctx->comp_data->string_literal_lengths_wp[contents]);
  373. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  374. param_values, 2, "create_stringref"))) {
  375. aot_set_last_error("llvm build call failed.");
  376. goto fail;
  377. }
  378. CHECK_STRING_OBJ(str_obj);
  379. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  380. WASM_TYPE_STRINGREF, 0,
  381. &stringref_obj)) {
  382. goto fail;
  383. }
  384. CHECK_STRINGREF_OBJ(stringref_obj);
  385. PUSH_GC_REF(stringref_obj);
  386. return true;
  387. fail:
  388. return false;
  389. }
  390. bool
  391. aot_compile_op_string_measure(AOTCompContext *comp_ctx,
  392. AOTFuncContext *func_ctx, uint32 encoding)
  393. {
  394. LLVMValueRef stringref_obj, value;
  395. POP_GC_REF(stringref_obj);
  396. if (!(value = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  397. stringref_obj, encoding))) {
  398. goto fail;
  399. }
  400. PUSH_I32(value);
  401. return true;
  402. fail:
  403. return false;
  404. }
  405. bool
  406. aot_compile_op_string_encode(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  407. uint32 mem_idx, uint32 encoding)
  408. {
  409. LLVMValueRef param_values[6], func, value, offset, length, maddr, str_obj,
  410. stringref_obj;
  411. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  412. LLVMBasicBlockRef check_string_encode_succ;
  413. LLVMValueRef cmp;
  414. POP_I32(offset);
  415. POP_GC_REF(stringref_obj);
  416. if (!(str_obj =
  417. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  418. goto fail;
  419. }
  420. if (!(length = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  421. stringref_obj, encoding))) {
  422. goto fail;
  423. }
  424. if (!(maddr =
  425. check_bulk_memory_overflow(comp_ctx, func_ctx, offset, length)))
  426. goto fail;
  427. param_types[0] = INT8_PTR_TYPE;
  428. param_types[1] = I32_TYPE;
  429. param_types[2] = I32_TYPE;
  430. param_types[3] = INT8_PTR_TYPE;
  431. param_types[4] = INT8_PTR_TYPE;
  432. param_types[5] = I32_TYPE;
  433. ret_type = I32_TYPE;
  434. GET_AOT_FUNCTION(wasm_string_encode, 6);
  435. /* Call function wasm_string_measure() */
  436. param_values[0] = str_obj;
  437. param_values[1] = I32_ZERO;
  438. param_values[2] = length;
  439. param_values[3] = maddr;
  440. param_values[4] = I8_PTR_NULL;
  441. param_values[5] = I32_CONST(encoding);
  442. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  443. param_values, 6, "string_encode"))) {
  444. aot_set_last_error("llvm build call failed.");
  445. goto fail;
  446. }
  447. CHECK_STRING_ENCODE(value);
  448. PUSH_I32(value);
  449. return true;
  450. fail:
  451. return false;
  452. }
  453. bool
  454. aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  455. const uint8 *frame_ip_string_concat)
  456. {
  457. LLVMValueRef param_values[2], func, value, str_obj_lhs, str_obj_rhs,
  458. stringref_obj_lhs, stringref_obj_rhs, stringref_obj_new;
  459. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  460. DEFINE_STRINGREF_CHECK_VAR();
  461. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  462. return false;
  463. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  464. frame_ip_string_concat))
  465. return false;
  466. POP_GC_REF(stringref_obj_rhs);
  467. POP_GC_REF(stringref_obj_lhs);
  468. if (!(str_obj_lhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  469. stringref_obj_lhs))) {
  470. goto fail;
  471. }
  472. if (!(str_obj_rhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  473. stringref_obj_rhs))) {
  474. goto fail;
  475. }
  476. param_types[0] = INT8_PTR_TYPE;
  477. param_types[1] = INT8_PTR_TYPE;
  478. ret_type = INT8_PTR_TYPE;
  479. GET_AOT_FUNCTION(wasm_string_concat, 2);
  480. /* Call function wasm_string_concat() */
  481. param_values[0] = str_obj_lhs;
  482. param_values[1] = str_obj_rhs;
  483. if (!(str_obj_lhs = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  484. param_values, 2, "string_concat"))) {
  485. aot_set_last_error("llvm build call failed.");
  486. goto fail;
  487. }
  488. CHECK_STRING_OBJ(str_obj_lhs);
  489. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj_lhs,
  490. WASM_TYPE_STRINGREF, 0,
  491. &stringref_obj_new)) {
  492. goto fail;
  493. }
  494. CHECK_STRINGREF_OBJ(stringref_obj_new);
  495. PUSH_GC_REF(stringref_obj_new);
  496. return true;
  497. fail:
  498. return false;
  499. }
  500. bool
  501. aot_compile_op_string_eq(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  502. {
  503. LLVMValueRef param_values[2], func, value, str_obj_lhs, str_obj_rhs,
  504. stringref_obj_lhs, stringref_obj_rhs;
  505. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  506. POP_GC_REF(stringref_obj_lhs);
  507. POP_GC_REF(stringref_obj_rhs);
  508. if (!(str_obj_lhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  509. stringref_obj_lhs))) {
  510. goto fail;
  511. }
  512. if (!(str_obj_rhs = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  513. stringref_obj_rhs))) {
  514. goto fail;
  515. }
  516. param_types[0] = INT8_PTR_TYPE;
  517. param_types[1] = INT8_PTR_TYPE;
  518. ret_type = I32_TYPE;
  519. GET_AOT_FUNCTION(wasm_string_eq, 2);
  520. /* Call function wasm_string_eq() */
  521. param_values[0] = str_obj_lhs;
  522. param_values[1] = str_obj_rhs;
  523. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  524. param_values, 2, "string_eq"))) {
  525. aot_set_last_error("llvm build call failed.");
  526. goto fail;
  527. }
  528. PUSH_I32(value);
  529. return true;
  530. fail:
  531. return false;
  532. }
  533. bool
  534. aot_compile_op_string_is_usv_sequence(AOTCompContext *comp_ctx,
  535. AOTFuncContext *func_ctx)
  536. {
  537. LLVMValueRef param_values[1], func, value, str_obj, stringref_obj;
  538. LLVMTypeRef param_types[1], ret_type, func_type, func_ptr_type;
  539. POP_GC_REF(stringref_obj);
  540. if (!(str_obj =
  541. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  542. goto fail;
  543. }
  544. param_types[0] = INT8_PTR_TYPE;
  545. ret_type = I32_TYPE;
  546. GET_AOT_FUNCTION(wasm_string_is_usv_sequence, 1);
  547. /* Call function wasm_string_is_usv_sequence() */
  548. param_values[0] = str_obj;
  549. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  550. param_values, 1, "string_is_usv_sequence"))) {
  551. aot_set_last_error("llvm build call failed.");
  552. goto fail;
  553. }
  554. PUSH_I32(value);
  555. return true;
  556. fail:
  557. return false;
  558. }
  559. bool
  560. aot_compile_op_string_as_wtf8(AOTCompContext *comp_ctx,
  561. AOTFuncContext *func_ctx,
  562. const uint8 *frame_ip_string_as_wtf8)
  563. {
  564. LLVMValueRef str_obj, stringref_obj, stringview_wtf8_obj;
  565. DEFINE_STRINGREF_CHECK_VAR();
  566. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  567. return false;
  568. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  569. frame_ip_string_as_wtf8))
  570. return false;
  571. POP_GC_REF(stringref_obj);
  572. if (!(str_obj = aot_call_wasm_string_create_view(
  573. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF8))) {
  574. goto fail;
  575. }
  576. CHECK_STRING_OBJ(str_obj);
  577. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  578. WASM_TYPE_STRINGVIEWWTF8, 0,
  579. &stringview_wtf8_obj)) {
  580. goto fail;
  581. }
  582. CHECK_STRINGVIEW_OBJ(stringref_obj);
  583. PUSH_GC_REF(stringview_wtf8_obj);
  584. return true;
  585. fail:
  586. return false;
  587. }
  588. bool
  589. aot_compile_op_stringview_wtf8_advance(AOTCompContext *comp_ctx,
  590. AOTFuncContext *func_ctx)
  591. {
  592. LLVMValueRef stringref_obj, bytes, pos, value;
  593. POP_I32(bytes);
  594. POP_I32(pos);
  595. POP_GC_REF(stringref_obj);
  596. if (!(value = aot_call_wasm_string_advance(comp_ctx, func_ctx,
  597. stringref_obj, bytes, pos))) {
  598. goto fail;
  599. }
  600. PUSH_I32(value);
  601. return true;
  602. fail:
  603. return false;
  604. }
  605. bool
  606. aot_compile_op_stringview_wtf8_encode(AOTCompContext *comp_ctx,
  607. AOTFuncContext *func_ctx, uint32 mem_idx,
  608. uint32 encoding)
  609. {
  610. LLVMValueRef param_values[6], func, value, offset, maddr, str_obj,
  611. stringref_obj;
  612. LLVMValueRef bytes, pos, next_pos;
  613. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  614. LLVMBasicBlockRef check_string_encode_succ;
  615. LLVMValueRef cmp;
  616. POP_I32(bytes);
  617. POP_I32(pos);
  618. POP_I32(offset);
  619. next_pos = LLVMBuildAlloca(comp_ctx->builder, I32_TYPE, "next_pos");
  620. if (!next_pos) {
  621. aot_set_last_error("failed to build alloca");
  622. goto fail;
  623. }
  624. if (!(maddr =
  625. check_bulk_memory_overflow(comp_ctx, func_ctx, offset, bytes)))
  626. goto fail;
  627. POP_GC_REF(stringref_obj);
  628. if (!(str_obj =
  629. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  630. goto fail;
  631. }
  632. param_types[0] = INT8_PTR_TYPE;
  633. param_types[1] = I32_TYPE;
  634. param_types[2] = I32_TYPE;
  635. param_types[3] = INT8_PTR_TYPE;
  636. param_types[4] = INT8_PTR_TYPE;
  637. param_types[5] = I32_TYPE;
  638. ret_type = I32_TYPE;
  639. GET_AOT_FUNCTION(wasm_string_encode, 6);
  640. /* Call function wasm_string_measure() */
  641. param_values[0] = str_obj;
  642. param_values[1] = pos;
  643. param_values[2] = bytes;
  644. param_values[3] = maddr;
  645. param_values[4] = next_pos;
  646. param_values[5] = I32_CONST(encoding);
  647. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  648. param_values, 6, "string_encode"))) {
  649. aot_set_last_error("llvm build call failed.");
  650. goto fail;
  651. }
  652. CHECK_STRING_ENCODE(value);
  653. next_pos =
  654. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, next_pos, "next_pos");
  655. if (!next_pos) {
  656. aot_set_last_error("llvm build load failed.");
  657. goto fail;
  658. }
  659. LLVMSetAlignment(next_pos, 4);
  660. PUSH_I32(next_pos);
  661. PUSH_I32(value);
  662. return true;
  663. fail:
  664. return false;
  665. }
  666. bool
  667. aot_compile_op_stringview_wtf8_slice(AOTCompContext *comp_ctx,
  668. AOTFuncContext *func_ctx,
  669. const uint8 *frame_ip_wtf8_slice)
  670. {
  671. LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
  672. DEFINE_STRINGREF_CHECK_VAR();
  673. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  674. return false;
  675. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  676. frame_ip_wtf8_slice))
  677. return false;
  678. POP_I32(start);
  679. POP_I32(end);
  680. POP_GC_REF(stringref_obj);
  681. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx, stringref_obj,
  682. start, end, STRING_VIEW_WTF8))) {
  683. goto fail;
  684. }
  685. CHECK_STRING_OBJ(value);
  686. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  687. WASM_TYPE_STRINGREF, 0,
  688. &stringref_obj_new)) {
  689. goto fail;
  690. }
  691. CHECK_STRINGREF_OBJ(stringref_obj_new);
  692. PUSH_GC_REF(stringref_obj_new);
  693. return true;
  694. fail:
  695. return false;
  696. }
  697. bool
  698. aot_compile_op_string_as_wtf16(AOTCompContext *comp_ctx,
  699. AOTFuncContext *func_ctx,
  700. const uint8 *frame_ip_string_as_wtf16)
  701. {
  702. LLVMValueRef str_obj, stringref_obj, stringview_wtf16_obj;
  703. DEFINE_STRINGREF_CHECK_VAR();
  704. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  705. return false;
  706. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  707. frame_ip_string_as_wtf16))
  708. return false;
  709. POP_GC_REF(stringref_obj);
  710. if (!(str_obj = aot_call_wasm_string_create_view(
  711. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF16))) {
  712. goto fail;
  713. }
  714. CHECK_STRING_OBJ(str_obj);
  715. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  716. WASM_TYPE_STRINGVIEWWTF16, 0,
  717. &stringview_wtf16_obj)) {
  718. goto fail;
  719. }
  720. CHECK_STRINGVIEW_OBJ(stringview_wtf16_obj);
  721. PUSH_GC_REF(stringview_wtf16_obj);
  722. return true;
  723. fail:
  724. return false;
  725. }
  726. bool
  727. aot_compile_op_stringview_wtf16_length(AOTCompContext *comp_ctx,
  728. AOTFuncContext *func_ctx)
  729. {
  730. LLVMValueRef param_values[2], func, value, str_obj, stringview_wtf16_obj;
  731. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  732. POP_GC_REF(stringview_wtf16_obj);
  733. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  734. stringview_wtf16_obj))) {
  735. goto fail;
  736. }
  737. param_types[0] = INT8_PTR_TYPE;
  738. ret_type = I32_TYPE;
  739. GET_AOT_FUNCTION(wasm_string_wtf16_get_length, 6);
  740. /* Call function wasm_string_wtf16_get_length() */
  741. param_values[0] = str_obj;
  742. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  743. param_values, 1, "stringview_wtf16_length"))) {
  744. aot_set_last_error("llvm build call failed.");
  745. goto fail;
  746. }
  747. PUSH_I32(value);
  748. return true;
  749. fail:
  750. return false;
  751. }
  752. bool
  753. aot_compile_op_stringview_wtf16_get_codeunit(AOTCompContext *comp_ctx,
  754. AOTFuncContext *func_ctx)
  755. {
  756. LLVMValueRef param_values[2], func, value, str_obj, stringview_wtf16_obj,
  757. pos;
  758. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  759. POP_I32(pos);
  760. POP_GC_REF(stringview_wtf16_obj);
  761. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  762. stringview_wtf16_obj))) {
  763. goto fail;
  764. }
  765. param_types[0] = INT8_PTR_TYPE;
  766. param_types[1] = I32_TYPE;
  767. ret_type = I32_TYPE;
  768. GET_AOT_FUNCTION(wasm_string_get_wtf16_codeunit, 2);
  769. /* Call function wasm_string_get_wtf16_codeunit() */
  770. param_values[0] = str_obj;
  771. param_values[1] = pos;
  772. if (!(value =
  773. LLVMBuildCall2(comp_ctx->builder, func_type, func, param_values,
  774. 2, "stringview_wtf16_get_codeunit"))) {
  775. aot_set_last_error("llvm build call failed.");
  776. goto fail;
  777. }
  778. PUSH_I32(value);
  779. return true;
  780. fail:
  781. return false;
  782. }
  783. bool
  784. aot_compile_op_stringview_wtf16_encode(AOTCompContext *comp_ctx,
  785. AOTFuncContext *func_ctx, uint32 mem_idx)
  786. {
  787. LLVMValueRef param_values[6], func, value, offset, maddr, str_obj,
  788. stringref_obj;
  789. LLVMValueRef len, pos;
  790. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  791. LLVMBasicBlockRef check_string_encode_succ;
  792. LLVMValueRef cmp;
  793. POP_I32(len);
  794. POP_I32(pos);
  795. POP_I32(offset);
  796. if (!(maddr = check_bulk_memory_overflow(
  797. comp_ctx, func_ctx, offset,
  798. LLVMBuildMul(comp_ctx->builder, len, I32_CONST(2), "wtf16_len"))))
  799. goto fail;
  800. POP_GC_REF(stringref_obj);
  801. if (!check_memory_alignment(comp_ctx, func_ctx, maddr, 2)) {
  802. goto fail;
  803. }
  804. if (!(str_obj =
  805. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  806. goto fail;
  807. }
  808. param_types[0] = INT8_PTR_TYPE;
  809. param_types[1] = I32_TYPE;
  810. param_types[2] = I32_TYPE;
  811. param_types[3] = INT8_PTR_TYPE;
  812. param_types[4] = INT8_PTR_TYPE;
  813. param_types[5] = I32_TYPE;
  814. ret_type = I32_TYPE;
  815. GET_AOT_FUNCTION(wasm_string_encode, 6);
  816. /* Call function wasm_string_measure() */
  817. param_values[0] = str_obj;
  818. param_values[1] = pos;
  819. param_values[2] = len;
  820. param_values[3] = maddr;
  821. param_values[4] = I8_PTR_NULL;
  822. param_values[5] = I32_CONST(WTF16);
  823. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  824. param_values, 6, "string_encode"))) {
  825. aot_set_last_error("llvm build call failed.");
  826. goto fail;
  827. }
  828. CHECK_STRING_ENCODE(value);
  829. PUSH_I32(value);
  830. return true;
  831. fail:
  832. return false;
  833. }
  834. bool
  835. aot_compile_op_stringview_wtf16_slice(AOTCompContext *comp_ctx,
  836. AOTFuncContext *func_ctx,
  837. const uint8 *frame_ip_wtf16_slice)
  838. {
  839. LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
  840. DEFINE_STRINGREF_CHECK_VAR();
  841. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  842. return false;
  843. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  844. frame_ip_wtf16_slice))
  845. return false;
  846. POP_I32(end);
  847. POP_I32(start);
  848. POP_GC_REF(stringref_obj);
  849. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx, stringref_obj,
  850. start, end, STRING_VIEW_WTF16))) {
  851. goto fail;
  852. }
  853. CHECK_STRING_OBJ(value);
  854. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  855. WASM_TYPE_STRINGREF, 0,
  856. &stringref_obj_new)) {
  857. goto fail;
  858. }
  859. CHECK_STRINGREF_OBJ(stringref_obj_new);
  860. PUSH_GC_REF(stringref_obj_new);
  861. return true;
  862. fail:
  863. return false;
  864. }
  865. bool
  866. aot_compile_op_string_as_iter(AOTCompContext *comp_ctx,
  867. AOTFuncContext *func_ctx,
  868. const uint8 *frame_ip_string_as_iter)
  869. {
  870. LLVMValueRef stringref_obj, stringview_iter_obj, str_obj;
  871. DEFINE_STRINGREF_CHECK_VAR();
  872. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  873. return false;
  874. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  875. frame_ip_string_as_iter))
  876. return false;
  877. POP_GC_REF(stringref_obj);
  878. if (!(str_obj = aot_call_wasm_string_create_view(
  879. comp_ctx, func_ctx, stringref_obj, STRING_VIEW_WTF8))) {
  880. goto fail;
  881. }
  882. CHECK_STRING_OBJ(str_obj);
  883. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, stringref_obj,
  884. WASM_TYPE_STRINGVIEWITER, 0,
  885. &stringview_iter_obj)) {
  886. goto fail;
  887. }
  888. CHECK_STRINGVIEW_OBJ(stringview_iter_obj);
  889. PUSH_GC_REF(stringview_iter_obj);
  890. return true;
  891. fail:
  892. return false;
  893. }
  894. bool
  895. aot_compile_op_stringview_iter_next(AOTCompContext *comp_ctx,
  896. AOTFuncContext *func_ctx)
  897. {
  898. LLVMValueRef param_values[2], func, value, stringview_iter_obj, str_obj,
  899. iter_pos_addr, pos;
  900. LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
  901. POP_GC_REF(stringview_iter_obj);
  902. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  903. stringview_iter_obj))) {
  904. goto fail;
  905. }
  906. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  907. stringview_iter_obj))) {
  908. goto fail;
  909. }
  910. pos = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  911. "get_iter_pos");
  912. LLVMSetAlignment(pos, 4);
  913. param_types[0] = INT8_PTR_TYPE;
  914. param_types[1] = I32_TYPE;
  915. ret_type = I32_TYPE;
  916. GET_AOT_FUNCTION(wasm_string_next_codepoint, 2);
  917. /* Call function wasm_string_measure() */
  918. param_values[0] = str_obj;
  919. param_values[1] = pos;
  920. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  921. param_values, 2, "stringview_iter_next"))) {
  922. aot_set_last_error("llvm build call failed.");
  923. goto fail;
  924. }
  925. PUSH_I32(value);
  926. return true;
  927. fail:
  928. return false;
  929. }
  930. static bool
  931. stringview_iter_advance_or_rewind(AOTCompContext *comp_ctx,
  932. AOTFuncContext *func_ctx, bool is_rewind)
  933. {
  934. LLVMValueRef param_values[4], func, value, stringview_iter_obj, str_obj,
  935. code_points_consumed, iter_pos_addr, pos, code_points_count, res;
  936. LLVMTypeRef param_types[4], ret_type, func_type, func_ptr_type;
  937. POP_I32(code_points_count);
  938. POP_GC_REF(stringview_iter_obj);
  939. if (!(str_obj = aot_stringref_obj_get_value(comp_ctx, func_ctx,
  940. stringview_iter_obj))) {
  941. goto fail;
  942. }
  943. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  944. stringview_iter_obj))) {
  945. goto fail;
  946. }
  947. if (!(pos = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  948. "get_iter_pos"))) {
  949. goto fail;
  950. }
  951. LLVMSetAlignment(pos, 4);
  952. if (!(code_points_consumed = LLVMBuildAlloca(comp_ctx->builder, I32_TYPE,
  953. "code_points_consumed"))) {
  954. goto fail;
  955. }
  956. param_types[0] = INT8_PTR_TYPE;
  957. param_types[1] = I32_TYPE;
  958. param_types[2] = I32_TYPE;
  959. param_types[3] = INT32_PTR_TYPE;
  960. ret_type = I32_TYPE;
  961. if (is_rewind) {
  962. GET_AOT_FUNCTION(wasm_string_rewind, 4);
  963. }
  964. else {
  965. GET_AOT_FUNCTION(wasm_string_advance, 4);
  966. }
  967. /* Call function wasm_string_advance() */
  968. param_values[0] = str_obj;
  969. param_values[1] = pos;
  970. param_values[2] = code_points_count;
  971. param_values[3] = code_points_consumed;
  972. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  973. param_values, 4, "string_advance"))) {
  974. aot_set_last_error("llvm build call failed.");
  975. goto fail;
  976. }
  977. if (!(code_points_consumed =
  978. LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, code_points_consumed,
  979. "get_code_points_consumed"))) {
  980. aot_set_last_error("llvm build load failed.");
  981. goto fail;
  982. }
  983. LLVMSetAlignment(code_points_consumed, 4);
  984. if (!(res = LLVMBuildStore(comp_ctx->builder, code_points_consumed,
  985. iter_pos_addr))) {
  986. aot_set_last_error("llvm build store failed.");
  987. goto fail;
  988. }
  989. LLVMSetAlignment(res, 4);
  990. PUSH_I32(code_points_consumed);
  991. fail:
  992. return false;
  993. }
  994. bool
  995. aot_compile_op_stringview_iter_advance(AOTCompContext *comp_ctx,
  996. AOTFuncContext *func_ctx)
  997. {
  998. return stringview_iter_advance_or_rewind(comp_ctx, func_ctx, false);
  999. }
  1000. bool
  1001. aot_compile_op_stringview_iter_rewind(AOTCompContext *comp_ctx,
  1002. AOTFuncContext *func_ctx)
  1003. {
  1004. return stringview_iter_advance_or_rewind(comp_ctx, func_ctx, true);
  1005. }
  1006. bool
  1007. aot_compile_op_stringview_iter_slice(
  1008. AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  1009. const uint8 *frame_ip_stringview_iter_slice)
  1010. {
  1011. LLVMValueRef stringview_iter_obj, start, end, stringref_obj_new, value,
  1012. iter_pos_addr, code_points_count;
  1013. DEFINE_STRINGREF_CHECK_VAR();
  1014. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  1015. return false;
  1016. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  1017. frame_ip_stringview_iter_slice))
  1018. return false;
  1019. POP_I32(code_points_count);
  1020. POP_GC_REF(stringview_iter_obj);
  1021. if (!(iter_pos_addr = get_stringview_iter_pos_addr(comp_ctx, func_ctx,
  1022. stringview_iter_obj))) {
  1023. goto fail;
  1024. }
  1025. if (!(start = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, iter_pos_addr,
  1026. "get_iter_pos"))) {
  1027. goto fail;
  1028. }
  1029. LLVMSetAlignment(start, 4);
  1030. if (!(end = LLVMBuildAdd(comp_ctx->builder, start, code_points_count,
  1031. "calc_slice_end"))) {
  1032. goto fail;
  1033. }
  1034. if (!(value = aot_call_wasm_string_slice(comp_ctx, func_ctx,
  1035. stringview_iter_obj, start, end,
  1036. STRING_VIEW_ITER))) {
  1037. goto fail;
  1038. }
  1039. CHECK_STRING_OBJ(value);
  1040. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, value,
  1041. WASM_TYPE_STRINGREF, 0,
  1042. &stringref_obj_new)) {
  1043. goto fail;
  1044. }
  1045. CHECK_STRINGREF_OBJ(stringref_obj_new);
  1046. PUSH_GC_REF(stringref_obj_new);
  1047. return true;
  1048. fail:
  1049. return false;
  1050. }
  1051. bool
  1052. aot_compile_op_string_new_array(AOTCompContext *comp_ctx,
  1053. AOTFuncContext *func_ctx, uint32 encoding,
  1054. const uint8 *frame_ip_string_new_array)
  1055. {
  1056. LLVMValueRef start, end, count, str_obj, stringref_obj, array_obj,
  1057. elem_data_ptr;
  1058. LLVMValueRef param_values[5], func, value;
  1059. LLVMTypeRef param_types[5], ret_type, func_type, func_ptr_type;
  1060. DEFINE_STRINGREF_CHECK_VAR();
  1061. if (!aot_gen_commit_values(comp_ctx->aot_frame))
  1062. return false;
  1063. if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
  1064. frame_ip_string_new_array))
  1065. return false;
  1066. POP_I32(end);
  1067. POP_I32(start);
  1068. POP_GC_REF(array_obj);
  1069. if (!aot_array_obj_elem_addr(
  1070. comp_ctx, func_ctx, array_obj, start, &elem_data_ptr,
  1071. encoding == WTF16 ? PACKED_TYPE_I16 : PACKED_TYPE_I8)) {
  1072. goto fail;
  1073. }
  1074. if (!(count = LLVMBuildSub(comp_ctx->builder, end, start, "calc_count"))) {
  1075. goto fail;
  1076. }
  1077. param_types[0] = INT8_PTR_TYPE;
  1078. param_types[1] = I32_TYPE;
  1079. param_types[2] = I32_TYPE;
  1080. ret_type = INT8_PTR_TYPE;
  1081. GET_AOT_FUNCTION(wasm_string_new_with_encoding, 3);
  1082. /* Call function wasm_struct_obj_new() */
  1083. param_values[0] = elem_data_ptr;
  1084. param_values[1] = count;
  1085. param_values[2] = I32_CONST(encoding);
  1086. if (!(str_obj = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  1087. param_values, 3, "wasm_string_new"))) {
  1088. aot_set_last_error("llvm build call failed.");
  1089. goto fail;
  1090. }
  1091. CHECK_STRING_OBJ(str_obj);
  1092. if (!aot_call_wasm_stringref_obj_new(comp_ctx, func_ctx, str_obj,
  1093. WASM_TYPE_STRINGREF, 0,
  1094. &stringref_obj)) {
  1095. goto fail;
  1096. }
  1097. CHECK_STRINGREF_OBJ(stringref_obj);
  1098. PUSH_GC_REF(stringref_obj);
  1099. return true;
  1100. fail:
  1101. return false;
  1102. }
  1103. bool
  1104. aot_compile_op_string_encode_array(AOTCompContext *comp_ctx,
  1105. AOTFuncContext *func_ctx, uint32 encoding)
  1106. {
  1107. LLVMValueRef param_values[6], func, value, count, start, str_obj,
  1108. stringref_obj, array_obj, elem_data_ptr, array_len;
  1109. LLVMTypeRef param_types[6], ret_type, func_type, func_ptr_type;
  1110. LLVMBasicBlockRef check_string_encode_succ, check_array_index_succ;
  1111. LLVMValueRef cmp;
  1112. POP_I32(start);
  1113. POP_GC_REF(array_obj);
  1114. POP_GC_REF(stringref_obj);
  1115. if (!(str_obj =
  1116. aot_stringref_obj_get_value(comp_ctx, func_ctx, stringref_obj))) {
  1117. goto fail;
  1118. }
  1119. if (!aot_array_obj_length(comp_ctx, array_obj, &array_len))
  1120. goto fail;
  1121. if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGE, start, array_len,
  1122. "check_array_index"))) {
  1123. aot_set_last_error("llvm build icmp failed.");
  1124. goto fail;
  1125. }
  1126. ADD_BASIC_BLOCK(check_array_index_succ, "check array index succ");
  1127. MOVE_BLOCK_AFTER_CURR(check_array_index_succ);
  1128. if (!aot_emit_exception(comp_ctx, func_ctx, EXCE_ARRAY_IDX_OOB, true, cmp,
  1129. check_array_index_succ)) {
  1130. goto fail;
  1131. }
  1132. if (!aot_array_obj_elem_addr(
  1133. comp_ctx, func_ctx, stringref_obj, start, &elem_data_ptr,
  1134. encoding == WTF16 ? PACKED_TYPE_I16 : PACKED_TYPE_I8)) {
  1135. goto fail;
  1136. }
  1137. if (!(count = aot_call_wasm_string_measure(comp_ctx, func_ctx,
  1138. stringref_obj, encoding))) {
  1139. goto fail;
  1140. }
  1141. param_types[0] = INT8_PTR_TYPE;
  1142. param_types[1] = I32_TYPE;
  1143. param_types[2] = I32_TYPE;
  1144. param_types[3] = INT8_PTR_TYPE;
  1145. param_types[4] = INT8_PTR_TYPE;
  1146. param_types[5] = I32_TYPE;
  1147. ret_type = I32_TYPE;
  1148. GET_AOT_FUNCTION(wasm_string_encode, 6);
  1149. /* Call function wasm_string_measure() */
  1150. param_values[0] = str_obj;
  1151. param_values[1] = start;
  1152. param_values[2] = count;
  1153. param_values[3] = elem_data_ptr;
  1154. param_values[4] = I8_PTR_NULL;
  1155. param_values[5] = I32_CONST(encoding);
  1156. if (!(value = LLVMBuildCall2(comp_ctx->builder, func_type, func,
  1157. param_values, 6, "string_encode"))) {
  1158. aot_set_last_error("llvm build call failed.");
  1159. goto fail;
  1160. }
  1161. CHECK_STRING_ENCODE(value);
  1162. PUSH_I32(value);
  1163. return true;
  1164. fail:
  1165. return false;
  1166. }
  1167. #endif /* WASM_ENABLE_STRINGREF != 0 */