Skip to content
This repository
  • 1 commit
  • 1 file changed
  • 0 comments
  • 1 contributor

Showing 1 changed file with 288 additions and 117 deletions. Show diff stats Hide diff stats

  1. +288 117 src/call/args.c
405 src/call/args.c
@@ -64,6 +64,63 @@ static void assign_default_param_value(PARROT_INTERP,
64 64 __attribute__nonnull__(5)
65 65 FUNC_MODIFIES(*accessor);
66 66
  67 +static void assign_named_param_value(PARROT_INTERP,
  68 + INTVAL param_index,
  69 + INTVAL param_flags,
  70 + ARGIN(STRING *param_name),
  71 + ARGIN(void *arg_info),
  72 + ARGIN(PMC *call_object),
  73 + ARGIN_NULLOK(Hash *named_used_list),
  74 + ARGMOD(struct pcc_funcs_ptr *accessor))
  75 + __attribute__nonnull__(1)
  76 + __attribute__nonnull__(4)
  77 + __attribute__nonnull__(5)
  78 + __attribute__nonnull__(6)
  79 + __attribute__nonnull__(8)
  80 + FUNC_MODIFIES(*accessor);
  81 +
  82 +static INTVAL assign_named_slurpy_params(PARROT_INTERP,
  83 + INTVAL param_index,
  84 + ARGIN(void *arg_info),
  85 + ARGIN(PMC *call_object),
  86 + ARGIN(Hash *named_used_list),
  87 + ARGMOD(struct pcc_funcs_ptr *accessor))
  88 + __attribute__nonnull__(1)
  89 + __attribute__nonnull__(3)
  90 + __attribute__nonnull__(4)
  91 + __attribute__nonnull__(5)
  92 + __attribute__nonnull__(6)
  93 + FUNC_MODIFIES(*accessor);
  94 +
  95 +static void assign_positional_param_value(PARROT_INTERP,
  96 + INTVAL param_index,
  97 + INTVAL param_flags,
  98 + INTVAL arg_index,
  99 + ARGIN(void *arg_info),
  100 + ARGIN(PMC *call_object),
  101 + ARGIN_NULLOK(Hash *named_used_list),
  102 + ARGMOD(struct pcc_funcs_ptr *accessor))
  103 + __attribute__nonnull__(1)
  104 + __attribute__nonnull__(5)
  105 + __attribute__nonnull__(6)
  106 + __attribute__nonnull__(8)
  107 + FUNC_MODIFIES(*accessor);
  108 +
  109 +static INTVAL assign_positional_slurpy_params(PARROT_INTERP,
  110 + INTVAL param_index,
  111 + ARGIN(void *arg_info),
  112 + ARGIN(PMC *call_object),
  113 + INTVAL positional_args,
  114 + INTVAL arg_index,
  115 + INTVAL named_count,
  116 + ARGIN_NULLOK(Hash *named_used_list),
  117 + ARGMOD(struct pcc_funcs_ptr *accessor))
  118 + __attribute__nonnull__(1)
  119 + __attribute__nonnull__(3)
  120 + __attribute__nonnull__(4)
  121 + __attribute__nonnull__(9)
  122 + FUNC_MODIFIES(*accessor);
  123 +
67 124 PARROT_CAN_RETURN_NULL
68 125 PARROT_WARN_UNUSED_RESULT
69 126 static PMC* clone_key_arg(PARROT_INTERP, ARGIN(PMC *key))
@@ -237,6 +294,29 @@ static STRING** string_param_from_op(PARROT_INTERP,
237 294 PARROT_ASSERT_ARG(interp) \
238 295 , PARROT_ASSERT_ARG(arg_info) \
239 296 , PARROT_ASSERT_ARG(accessor))
  297 +#define ASSERT_ARGS_assign_named_param_value __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  298 + PARROT_ASSERT_ARG(interp) \
  299 + , PARROT_ASSERT_ARG(param_name) \
  300 + , PARROT_ASSERT_ARG(arg_info) \
  301 + , PARROT_ASSERT_ARG(call_object) \
  302 + , PARROT_ASSERT_ARG(accessor))
  303 +#define ASSERT_ARGS_assign_named_slurpy_params __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  304 + PARROT_ASSERT_ARG(interp) \
  305 + , PARROT_ASSERT_ARG(arg_info) \
  306 + , PARROT_ASSERT_ARG(call_object) \
  307 + , PARROT_ASSERT_ARG(named_used_list) \
  308 + , PARROT_ASSERT_ARG(accessor))
  309 +#define ASSERT_ARGS_assign_positional_param_value __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  310 + PARROT_ASSERT_ARG(interp) \
  311 + , PARROT_ASSERT_ARG(arg_info) \
  312 + , PARROT_ASSERT_ARG(call_object) \
  313 + , PARROT_ASSERT_ARG(accessor))
  314 +#define ASSERT_ARGS_assign_positional_slurpy_params \
  315 + __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  316 + PARROT_ASSERT_ARG(interp) \
  317 + , PARROT_ASSERT_ARG(arg_info) \
  318 + , PARROT_ASSERT_ARG(call_object) \
  319 + , PARROT_ASSERT_ARG(accessor))
240 320 #define ASSERT_ARGS_clone_key_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
241 321 PARROT_ASSERT_ARG(interp) \
242 322 , PARROT_ASSERT_ARG(key))
@@ -811,29 +891,9 @@ fill_params(PARROT_INTERP, ARGMOD_NULLOK(PMC *call_object),
811 891 if (param_flags & PARROT_ARG_SLURPY_ARRAY) {
812 892 /* Can't handle named slurpy here, go to named argument handling */
813 893 if (!(param_flags & PARROT_ARG_NAME)) {
814   - PMC *collect_positional;
815   - int j;
816   - INTVAL num_positionals = positional_args - arg_index;
817   - if (num_positionals < 0)
818   - num_positionals = 0;
819   - if (named_count > 0){
820   - if (named_used_list != NULL)
821   - parrot_hash_destroy(interp, named_used_list);
822   - Parrot_ex_throw_from_c_args(interp, NULL,
823   - EXCEPTION_INVALID_OPERATION,
824   - "named parameters must follow all positional parameters");
825   - }
826   -
827   - collect_positional = Parrot_pmc_new_init_int(interp,
828   - Parrot_hll_get_ctx_HLL_type(interp, enum_class_ResizablePMCArray),
829   - num_positionals);
830   -
831   - for (j = 0; arg_index < positional_args; ++arg_index)
832   - VTABLE_set_pmc_keyed_int(interp, collect_positional, j++,
833   - VTABLE_get_pmc_keyed_int(interp, call_object, arg_index));
834   -
835   - *accessor->pmc(interp, arg_info, param_index) = collect_positional;
836   - ++param_index;
  894 + arg_index += assign_positional_slurpy_params(interp,
  895 + param_index++, arg_info, call_object, positional_args,
  896 + arg_index, named_count, named_used_list, accessor);
837 897 }
838 898 break; /* Terminate the positional arg loop. */
839 899 }
@@ -879,31 +939,9 @@ fill_params(PARROT_INTERP, ARGMOD_NULLOK(PMC *call_object),
879 939
880 940 /* Check for :lookahead parameter goes here. */
881 941
882   - /* Go ahead and fill the parameter with a positional argument. */
883   - switch (PARROT_ARG_TYPE_MASK_MASK(param_flags)) {
884   - case PARROT_ARG_PMC:
885   - *accessor->pmc(interp, arg_info, param_index) =
886   - VTABLE_get_pmc_keyed_int(interp, call_object, arg_index);
887   - break;
888   - case PARROT_ARG_STRING:
889   - *accessor->string(interp, arg_info, param_index) =
890   - VTABLE_get_string_keyed_int(interp, call_object, arg_index);
891   - break;
892   - case PARROT_ARG_INTVAL:
893   - *accessor->intval(interp, arg_info, param_index) =
894   - VTABLE_get_integer_keyed_int(interp, call_object, arg_index);
895   - break;
896   - case PARROT_ARG_FLOATVAL:
897   - *accessor->numval(interp, arg_info, param_index) =
898   - VTABLE_get_number_keyed_int(interp, call_object, arg_index);
899   - break;
900   - default:
901   - if (named_used_list != NULL)
902   - parrot_hash_destroy(interp, named_used_list);
903   - Parrot_ex_throw_from_c_args(interp, NULL,
904   - EXCEPTION_INVALID_OPERATION, "invalid parameter type");
905   - break;
906   - }
  942 + /* Fill the positional parameter. */
  943 + assign_positional_param_value(interp, param_index, param_flags,
  944 + arg_index, arg_info, call_object, named_used_list, accessor);
907 945
908 946 /* Mark the option flag for the filled parameter. */
909 947 if (param_flags & PARROT_ARG_OPTIONAL) {
@@ -989,38 +1027,11 @@ fill_params(PARROT_INTERP, ARGMOD_NULLOK(PMC *call_object),
989 1027
990 1028 /* Collected ("slurpy") named parameter */
991 1029 if (param_flags & PARROT_ARG_SLURPY_ARRAY) {
992   - PMC * const collect_named = Parrot_pmc_new(interp,
993   - Parrot_hll_get_ctx_HLL_type(interp, enum_class_Hash));
994   - PMC * const named_arg_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "named"));
995   -
996   - if (!PMC_IS_NULL(named_arg_list)) {
997   - const INTVAL named_arg_count = VTABLE_elements(interp, named_arg_list);
998   - INTVAL named_arg_index;
999   -
1000   - /* Named argument iteration. */
1001   - for (named_arg_index = 0; named_arg_index < named_arg_count; ++named_arg_index) {
1002   - STRING * const name = VTABLE_get_string_keyed_int(interp,
1003   - named_arg_list, named_arg_index);
1004   -
1005   - if ((named_used_list == NULL)
1006   - || !parrot_hash_exists(interp, named_used_list, name)) {
1007   -
1008   - VTABLE_set_pmc_keyed_str(interp, collect_named, name,
1009   - VTABLE_get_pmc_keyed_str(interp, call_object, name));
1010   -
1011   - /* Mark the name as used, cannot be filled again. */
1012   - if (named_used_list==NULL) /* Only created if needed. */
1013   - named_used_list = parrot_create_hash(interp,
1014   - enum_type_INTVAL, Hash_key_type_STRING);
1015   -
1016   - parrot_hash_put(interp, named_used_list, name, (void *)1);
1017   -
1018   - ++named_count;
1019   - }
1020   - }
1021   - }
1022   -
1023   - *accessor->pmc(interp, arg_info, param_index) = collect_named;
  1030 + if (named_used_list == NULL)
  1031 + named_used_list = parrot_create_hash(interp,
  1032 + enum_type_INTVAL, Hash_key_type_STRING);
  1033 + named_count += assign_named_slurpy_params(interp, param_index,
  1034 + arg_info, call_object, named_used_list, accessor);
1024 1035 break; /* End of named parameters. */
1025 1036 }
1026 1037
@@ -1055,55 +1066,28 @@ fill_params(PARROT_INTERP, ARGMOD_NULLOK(PMC *call_object),
1055 1066 ++named_count;
1056 1067
1057 1068 /* Fill the named parameter. */
1058   - switch (PARROT_ARG_TYPE_MASK_MASK(param_flags)) {
1059   - case PARROT_ARG_INTVAL:
1060   - *accessor->intval(interp, arg_info, param_index) =
1061   - VTABLE_get_integer_keyed_str(interp, call_object, param_name);
1062   - break;
1063   - case PARROT_ARG_FLOATVAL:
1064   - *accessor->numval(interp, arg_info, param_index) =
1065   - VTABLE_get_number_keyed_str(interp, call_object, param_name);
1066   - break;
1067   - case PARROT_ARG_STRING:
1068   - *accessor->string(interp, arg_info, param_index) =
1069   - VTABLE_get_string_keyed_str(interp, call_object, param_name);
1070   - break;
1071   - case PARROT_ARG_PMC:
1072   - *accessor->pmc(interp, arg_info, param_index) =
1073   - VTABLE_get_pmc_keyed_str(interp, call_object, param_name);
1074   - break;
1075   - default:
1076   - if (named_used_list != NULL)
1077   - parrot_hash_destroy(interp, named_used_list);
1078   - Parrot_ex_throw_from_c_args(interp, NULL,
1079   - EXCEPTION_INVALID_OPERATION, "invalid parameter type");
1080   - break;
1081   - }
  1069 + assign_named_param_value(interp, param_index, param_flags,
  1070 + param_name, arg_info, call_object, named_used_list,
  1071 + accessor);
1082 1072
1083 1073 /* Mark the option flag for the filled parameter. */
1084   - if (param_flags & PARROT_ARG_OPTIONAL) {
1085   - if (param_index + 1 < param_count) {
1086   - const INTVAL next_param_flags = raw_params[param_index + 1];
1087   -
1088   - if (next_param_flags & PARROT_ARG_OPT_FLAG) {
1089   - ++param_index;
1090   - *accessor->intval(interp, arg_info, param_index) = 1;
1091   - }
  1074 + if (param_index + 1 < param_count) {
  1075 + const INTVAL next_param_flags = raw_params[param_index + 1];
  1076 +
  1077 + if (next_param_flags & PARROT_ARG_OPT_FLAG) {
  1078 + *accessor->intval(interp, arg_info, ++param_index) = 1;
1092 1079 }
1093 1080 }
1094 1081 }
1095 1082 else if (param_flags & PARROT_ARG_OPTIONAL) {
1096 1083 assign_default_param_value(interp, param_index, param_flags,
1097   - arg_info, accessor);
  1084 + arg_info, accessor);
1098 1085
1099   - /* Mark the option flag for the parameter to FALSE;
1100   - * it was filled with a default value. */
1101 1086 if (param_index + 1 < param_count) {
1102 1087 const INTVAL next_param_flags = raw_params[param_index + 1];
1103 1088
1104 1089 if (next_param_flags & PARROT_ARG_OPT_FLAG) {
1105   - ++param_index;
1106   - *accessor->intval(interp, arg_info, param_index) = 0;
  1090 + *accessor->intval(interp, arg_info, ++param_index) = 0;
1107 1091 }
1108 1092 }
1109 1093 }
@@ -1130,6 +1114,7 @@ fill_params(PARROT_INTERP, ARGMOD_NULLOK(PMC *call_object),
1130 1114 if (err_check) {
1131 1115 PMC *named_arg_list;
1132 1116 Hash *h;
  1117 +
1133 1118 /* Early exit to avoid vtable call */
1134 1119 GETATTR_CallContext_hash(interp, call_object, h);
1135 1120 if (!h || !h->entries){
@@ -1238,6 +1223,192 @@ assign_default_param_value(PARROT_INTERP, INTVAL param_index, INTVAL param_flags
1238 1223
1239 1224 /*
1240 1225
  1226 +=item C<static void assign_positional_param_value(PARROT_INTERP, INTVAL
  1227 +param_index, INTVAL param_flags, INTVAL arg_index, void *arg_info, PMC
  1228 +*call_object, Hash *named_used_list, struct pcc_funcs_ptr *accessor)>
  1229 +
  1230 +Assign values to the parameter using positional parameters.
  1231 +
  1232 +=cut
  1233 +
  1234 +*/
  1235 +
  1236 +static void
  1237 +assign_positional_param_value(PARROT_INTERP, INTVAL param_index,
  1238 + INTVAL param_flags, INTVAL arg_index, ARGIN(void *arg_info),
  1239 + ARGIN(PMC *call_object), ARGIN_NULLOK(Hash *named_used_list),
  1240 + ARGMOD(struct pcc_funcs_ptr *accessor))
  1241 +{
  1242 + ASSERT_ARGS(assign_positional_param_value)
  1243 + switch (PARROT_ARG_TYPE_MASK_MASK(param_flags)) {
  1244 + case PARROT_ARG_PMC:
  1245 + *accessor->pmc(interp, arg_info, param_index) =
  1246 + VTABLE_get_pmc_keyed_int(interp, call_object, arg_index);
  1247 + break;
  1248 + case PARROT_ARG_STRING:
  1249 + *accessor->string(interp, arg_info, param_index) =
  1250 + VTABLE_get_string_keyed_int(interp, call_object, arg_index);
  1251 + break;
  1252 + case PARROT_ARG_INTVAL:
  1253 + *accessor->intval(interp, arg_info, param_index) =
  1254 + VTABLE_get_integer_keyed_int(interp, call_object, arg_index);
  1255 + break;
  1256 + case PARROT_ARG_FLOATVAL:
  1257 + *accessor->numval(interp, arg_info, param_index) =
  1258 + VTABLE_get_number_keyed_int(interp, call_object, arg_index);
  1259 + break;
  1260 + default:
  1261 + if (named_used_list != NULL)
  1262 + parrot_hash_destroy(interp, named_used_list);
  1263 + Parrot_ex_throw_from_c_args(interp, NULL,
  1264 + EXCEPTION_INVALID_OPERATION, "invalid parameter type");
  1265 + break;
  1266 + }
  1267 +}
  1268 +
  1269 +/*
  1270 +
  1271 +=item C<static void assign_named_param_value(PARROT_INTERP, INTVAL param_index,
  1272 +INTVAL param_flags, STRING *param_name, void *arg_info, PMC *call_object, Hash
  1273 +*named_used_list, struct pcc_funcs_ptr *accessor)>
  1274 +
  1275 +Assign values to the parameter using named parameters.
  1276 +
  1277 +=cut
  1278 +
  1279 +*/
  1280 +
  1281 +static void
  1282 +assign_named_param_value(PARROT_INTERP, INTVAL param_index,
  1283 + INTVAL param_flags, ARGIN(STRING *param_name), ARGIN(void *arg_info),
  1284 + ARGIN(PMC *call_object), ARGIN_NULLOK(Hash *named_used_list),
  1285 + ARGMOD(struct pcc_funcs_ptr *accessor))
  1286 +{
  1287 + switch (PARROT_ARG_TYPE_MASK_MASK(param_flags)) {
  1288 +
  1289 + case PARROT_ARG_PMC:
  1290 + *accessor->pmc(interp, arg_info, param_index) =
  1291 + VTABLE_get_pmc_keyed_str(interp, call_object, param_name);
  1292 + break;
  1293 + case PARROT_ARG_STRING:
  1294 + *accessor->string(interp, arg_info, param_index) =
  1295 + VTABLE_get_string_keyed_str(interp, call_object, param_name);
  1296 + break;
  1297 + case PARROT_ARG_INTVAL:
  1298 + *accessor->intval(interp, arg_info, param_index) =
  1299 + VTABLE_get_integer_keyed_str(interp, call_object, param_name);
  1300 + break;
  1301 + case PARROT_ARG_FLOATVAL:
  1302 + *accessor->numval(interp, arg_info, param_index) =
  1303 + VTABLE_get_number_keyed_str(interp, call_object, param_name);
  1304 + break;
  1305 + default:
  1306 + if (named_used_list != NULL)
  1307 + parrot_hash_destroy(interp, named_used_list);
  1308 + Parrot_ex_throw_from_c_args(interp, NULL,
  1309 + EXCEPTION_INVALID_OPERATION, "invalid parameter type");
  1310 + break;
  1311 + }
  1312 +}
  1313 +
  1314 +/*
  1315 +
  1316 +=item C<static INTVAL assign_positional_slurpy_params(PARROT_INTERP, INTVAL
  1317 +param_index, void *arg_info, PMC *call_object, INTVAL positional_args, INTVAL
  1318 +arg_index, INTVAL named_count, Hash *named_used_list, struct pcc_funcs_ptr
  1319 +*accessor)>
  1320 +
  1321 +Assign all positional slurpy parameters. Returns the increase in argument index.
  1322 +
  1323 +=cut
  1324 +
  1325 +*/
  1326 +
  1327 +static INTVAL
  1328 +assign_positional_slurpy_params(PARROT_INTERP, INTVAL param_index,
  1329 + ARGIN(void *arg_info), ARGIN(PMC *call_object), INTVAL positional_args,
  1330 + INTVAL arg_index, INTVAL named_count, ARGIN_NULLOK(Hash *named_used_list),
  1331 + ARGMOD(struct pcc_funcs_ptr *accessor))
  1332 +{
  1333 + const INTVAL num_positionals = positional_args - arg_index > 0 ?
  1334 + positional_args - arg_index :
  1335 + 0;
  1336 +
  1337 + PMC * const collect_positional = Parrot_pmc_new_init_int(interp,
  1338 + Parrot_hll_get_ctx_HLL_type(interp, enum_class_ResizablePMCArray),
  1339 + num_positionals);
  1340 +
  1341 + INTVAL j;
  1342 +
  1343 + if (named_count > 0){
  1344 + if (named_used_list != NULL)
  1345 + parrot_hash_destroy(interp, named_used_list);
  1346 + Parrot_ex_throw_from_c_args(interp, NULL,
  1347 + EXCEPTION_INVALID_OPERATION,
  1348 + "named parameters must follow all positional parameters");
  1349 + }
  1350 +
  1351 + for (j = 0; arg_index < positional_args; ++arg_index)
  1352 + VTABLE_set_pmc_keyed_int(interp, collect_positional, j++,
  1353 + VTABLE_get_pmc_keyed_int(interp, call_object, arg_index));
  1354 +
  1355 + *accessor->pmc(interp, arg_info, param_index) = collect_positional;
  1356 +
  1357 + return j;
  1358 +}
  1359 +
  1360 +/*
  1361 +
  1362 +=item C<static INTVAL assign_named_slurpy_params(PARROT_INTERP, INTVAL
  1363 +param_index, void *arg_info, PMC *call_object, Hash *named_used_list, struct
  1364 +pcc_funcs_ptr *accessor)>
  1365 +
  1366 +Assign all named slurpy parameters. Returns the increase in named count.
  1367 +
  1368 +=cut
  1369 +
  1370 +*/
  1371 +
  1372 +static INTVAL
  1373 +assign_named_slurpy_params(PARROT_INTERP, INTVAL param_index,
  1374 + ARGIN(void *arg_info), ARGIN(PMC *call_object),
  1375 + ARGIN(Hash *named_used_list), ARGMOD(struct pcc_funcs_ptr *accessor))
  1376 +{
  1377 + PMC * const collect_named = Parrot_pmc_new(interp,
  1378 + Parrot_hll_get_ctx_HLL_type(interp, enum_class_Hash));
  1379 +
  1380 + PMC * const named_arg_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "named"));
  1381 +
  1382 + INTVAL j;
  1383 +
  1384 + if (!PMC_IS_NULL(named_arg_list)) {
  1385 + const INTVAL named_arg_count = VTABLE_elements(interp, named_arg_list);
  1386 + INTVAL named_arg_index;
  1387 +
  1388 + /* Named argument iteration. */
  1389 + for (named_arg_index = 0; named_arg_index < named_arg_count; ++named_arg_index) {
  1390 + STRING * const name = VTABLE_get_string_keyed_int(interp,
  1391 + named_arg_list, named_arg_index);
  1392 +
  1393 + if (!parrot_hash_exists(interp, named_used_list, name)) {
  1394 +
  1395 + VTABLE_set_pmc_keyed_str(interp, collect_named, name,
  1396 + VTABLE_get_pmc_keyed_str(interp, call_object, name));
  1397 +
  1398 + parrot_hash_put(interp, named_used_list, name, (void *)1);
  1399 +
  1400 + j++;
  1401 + }
  1402 + }
  1403 + }
  1404 +
  1405 + *accessor->pmc(interp, arg_info, param_index) = collect_named;
  1406 +
  1407 + return j;
  1408 +}
  1409 +
  1410 +/*
  1411 +
1241 1412 =item C<void Parrot_pcc_fill_params_from_op(PARROT_INTERP, PMC *call_object, PMC
1242 1413 *raw_sig, opcode_t *raw_params, Errors_classes direction)>
1243 1414

No commit comments for this range

Something went wrong with that request. Please try again.