disallow indexed reads of localvars declared non-map

This commit is contained in:
John Kerl 2016-12-12 21:26:22 -05:00
parent 127c949d49
commit 5a3466aebf
5 changed files with 82 additions and 44 deletions

View file

@ -106,6 +106,10 @@ mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe,
local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index];
mlhmmv_xvalue_t* pbase_xval = &pentry->xvalue;
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch_for_read(pentry);
}
#ifdef LOCAL_STACK_TRACE_ENABLE
// xxx needs an mlhmmv_xvalue_print
if (pbase_xval == NULL) {
@ -146,8 +150,8 @@ mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe,
}
// ----------------------------------------------------------------
mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index, sllmv_t* pmvkeys)
mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_nonindexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index)
{
LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index));
LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index);
@ -172,14 +176,43 @@ mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t
}
#endif
int error = 0;
// Maybe null
if (pmvkeys == NULL || pmvkeys->length == 0) {
return pmvalue;
} else {
return mlhmmv_level_look_up_and_ref_xvalue(pmvalue->pnext_level, pmvkeys, &error);
return pmvalue;
}
// ----------------------------------------------------------------
mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index, sllmv_t* pmvkeys)
{
LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index));
LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index);
local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index];
mlhmmv_xvalue_t* pmvalue = &pentry->xvalue;
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch_for_read(pentry);
}
#ifdef LOCAL_STACK_TRACE_ENABLE
// xxx needs an mlhmmv_xvalue_print
if (pmvalue == NULL) {
printf("VALUE IS NULL\n");
} else if (pmvalue->is_terminal) {
char* s = mv_alloc_format_val(&pmvalue->terminal_mlrval);
printf("VALUE IS %s\n", s);
free(s);
} else if (pmvalue->pnext_level == NULL) {
LOCAL_STACK_TRACE(printf("VALUE IS EMPTY\n"));
} else {
printf("VALUE IS:\n");
printf("PTR IS %p\n", pmvalue->pnext_level);
mlhmmv_level_print_stacked(pmvalue->pnext_level, 0, TRUE, TRUE, "", stdout);
}
#endif
int error = 0;
// Maybe null
return mlhmmv_level_look_up_and_ref_xvalue(pmvalue->pnext_level, pmvkeys, &error);
}
// ----------------------------------------------------------------
@ -194,7 +227,7 @@ void local_stack_frame_define_terminal(local_stack_frame_t* pframe, char* variab
pentry->type_mask = type_mask;
if (!(type_mask_from_mv(&val) & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &val);
local_stack_frame_throw_type_mismatch_for_write(pentry, &val);
}
mlhmmv_xvalue_free(&pentry->xvalue);
@ -219,11 +252,11 @@ void local_stack_frame_define_extended(local_stack_frame_t* pframe, char* variab
if (xval.is_terminal) {
if (!(type_mask_from_mv(&xval.terminal_mlrval) & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval);
local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval);
}
} else {
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval);
local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval);
}
}
@ -243,7 +276,7 @@ void local_stack_frame_assign_terminal_indexed(local_stack_frame_t* pframe,
local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index];
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &terminal_value);
local_stack_frame_throw_type_mismatch_for_write(pentry, &terminal_value);
}
mlhmmv_xvalue_t* pmvalue = &pentry->xvalue;
@ -268,11 +301,11 @@ void local_stack_frame_assign_extended_nonindexed(local_stack_frame_t* pframe,
if (xval.is_terminal) {
if (!(type_mask_from_mv(&xval.terminal_mlrval) & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval);
local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval);
}
} else {
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_mismatch(pentry, &xval.terminal_mlrval);
local_stack_frame_throw_type_mismatch_for_write(pentry, &xval.terminal_mlrval);
}
}
@ -290,7 +323,7 @@ void local_stack_frame_assign_extended_indexed(local_stack_frame_t* pframe,
local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index];
if (!(TYPE_MASK_MAP & pentry->type_mask)) {
local_stack_frame_throw_type_xmismatch(pentry, &new_value);
local_stack_frame_throw_type_xmismatch_for_write(pentry, &new_value);
}
mlhmmv_xvalue_t* pmvalue = &pentry->xvalue;
@ -331,7 +364,7 @@ void local_stack_bounds_check(local_stack_frame_t* pframe, char* op, int set, in
}
// ----------------------------------------------------------------
void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval) {
void local_stack_frame_throw_type_mismatch_for_write(local_stack_frame_entry_t* pentry, mv_t* pval) {
MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
char* sval = mv_alloc_format_val_quoting_strings(pval);
fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n",
@ -341,7 +374,7 @@ void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv
exit(1);
}
void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) {
void local_stack_frame_throw_type_xmismatch_for_write(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) {
MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
char* sval = mv_alloc_format_val_quoting_strings(&pxval->terminal_mlrval); // xxx temp
fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n",
@ -350,3 +383,18 @@ void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, m
free(sval);
exit(1);
}
// ----------------------------------------------------------------
void local_stack_frame_throw_type_mismatch_for_read(local_stack_frame_entry_t* pentry) {
MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
fprintf(stderr, "%s: %s type assertion for variable %s unmet on read.\n",
MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name);
exit(1);
}
void local_stack_frame_throw_type_xmismatch_for_read(local_stack_frame_entry_t* pentry) {
MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
fprintf(stderr, "%s: %s type assertion for variable %s unmet on read.\n",
MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name);
exit(1);
}

View file

@ -82,8 +82,10 @@ void local_stack_bounds_check(local_stack_frame_t* pframe, char* op, int set, in
local_stack_frame_t* local_stack_frame_enter(local_stack_frame_t* pframe);
void local_stack_frame_exit(local_stack_frame_t* pframe);
void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval);
void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval);
void local_stack_frame_throw_type_mismatch_for_write(local_stack_frame_entry_t* pentry, mv_t* pval);
void local_stack_frame_throw_type_xmismatch_for_write(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval);
void local_stack_frame_throw_type_mismatch_for_read(local_stack_frame_entry_t* pentry);
void local_stack_frame_throw_type_xmismatch_for_read(local_stack_frame_entry_t* pentry);
// ----------------------------------------------------------------
static inline mv_t local_stack_frame_get_terminal_from_nonindexed(local_stack_frame_t* pframe, // move to reference semantics
@ -109,7 +111,7 @@ static inline void local_stack_frame_assign_terminal_nonindexed(local_stack_fram
local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index];
if (!(type_mask_from_mv(&val) & pentry->type_mask)) { // xxx temp
local_stack_frame_throw_type_mismatch(pentry, &val);
local_stack_frame_throw_type_mismatch_for_write(pentry, &val);
}
mlhmmv_xvalue_free(&pentry->xvalue);
@ -120,6 +122,9 @@ static inline void local_stack_frame_assign_terminal_nonindexed(local_stack_fram
mv_t local_stack_frame_ref_terminal_from_indexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index, sllmv_t* pmvkeys);
mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_nonindexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index);
mlhmmv_xvalue_t* local_stack_frame_ref_extended_from_indexed(local_stack_frame_t* pframe,
int vardef_frame_relative_index, sllmv_t* pmvkeys);

View file

@ -240,27 +240,6 @@ static void cst_udf_type_check_return_value(cst_udf_state_t* pstate, mlhmmv_xval
}
}
// xxx incorp
//void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval) {
// MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
// char* sval = mv_alloc_format_val_quoting_strings(pval);
// fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n",
// MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name,
// sval, mt_describe_type_simple(pval->type));
// free(sval);
// exit(1);
//}
//
//void local_stack_frame_throw_type_xmismatch(local_stack_frame_entry_t* pentry, mlhmmv_xvalue_t* pxval) {
// MLR_INTERNAL_CODING_ERROR_IF(pentry->name == NULL);
// char* sval = mv_alloc_format_val_quoting_strings(&pxval->terminal_mlrval); // xxx temp
// fprintf(stderr, "%s: %s type assertion for variable %s unmet by value %s with type %s.\n",
// MLR_GLOBALS.bargv0, type_mask_to_desc(pentry->type_mask), pentry->name,
// sval, mlhmmv_xvalue_describe_type_simple(pxval));
// free(sval);
// exit(1);
//}
// ----------------------------------------------------------------
// Callback function for the function manager to invoke into here

View file

@ -265,8 +265,8 @@ typedef struct _rxval_evaluator_from_nonindexed_local_variable_state_t {
static boxed_xval_t rxval_evaluator_from_nonindexed_local_variable_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_nonindexed_local_variable_state_t* pstate = pvstate;
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_indexed(
pframe, pstate->vardef_frame_relative_index, NULL);
mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_nonindexed(
pframe, pstate->vardef_frame_relative_index);
if (pxval == NULL) {
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),

View file

@ -36,7 +36,8 @@ MAPVAR CHECKLIST:
! assert_map/assert_scalar/etc.
! this should throw an error: mlr --from s put 'int a=1;var b=a[2]'
! this should throw an error:
mlr --from ../c/s put 'int a=1;var b=a[2]'
! 'Local variables' 'Notes:' split into surprising and unsurprising
@ -171,6 +172,11 @@ k assign LHS full-srec from RHS func-retval alloc ephem & move
----------------------------------------------------------------
EXECUTION TRACE:
! missing operators
$ mlr --from ../c/s put -T 'int a=1;var b=a[2]'
TRACE (int a 1)
TRACE (var b (a 2))
! trace *assignments* (mutations of pvars state)
* work through the grammar & neaten up pnode->text instances, now that these names are user-visible.