@@ -54,6 +54,9 @@ pub(crate) struct OperatorValidator {
54
54
/// Offset of the `end` instruction which emptied the `control` stack, which
55
55
/// must be the end of the function.
56
56
end_which_emptied_control : Option < usize > ,
57
+
58
+ /// Whether validation is happening in a shared context.
59
+ shared : bool ,
57
60
}
58
61
59
62
// No science was performed in the creation of this number, feel free to change
@@ -274,6 +277,7 @@ impl OperatorValidator {
274
277
operands,
275
278
control,
276
279
end_which_emptied_control : None ,
280
+ shared : false ,
277
281
}
278
282
}
279
283
@@ -300,17 +304,30 @@ impl OperatorValidator {
300
304
unreachable : false ,
301
305
init_height : 0 ,
302
306
} ) ;
303
- let params = OperatorValidatorTemp {
304
- // This offset is used by the `func_type_at` and `inputs`.
307
+
308
+ // Retrieve the function's type via index (`ty`); the `offset` is
309
+ // necessary due to `sub_type_at`'s error messaging.
310
+ let sub_ty = OperatorValidatorTemp {
305
311
offset,
306
312
inner : & mut ret,
307
313
resources,
308
314
}
309
- . func_type_at ( ty) ?
310
- . params ( ) ;
311
- for ty in params {
312
- ret. locals . define ( 1 , * ty) ;
313
- ret. local_inits . push ( true ) ;
315
+ . sub_type_at ( ty) ?;
316
+
317
+ // Set up the function's locals.
318
+ if let CompositeInnerType :: Func ( func_ty) = & sub_ty. composite_type . inner {
319
+ for ty in func_ty. params ( ) {
320
+ ret. locals . define ( 1 , * ty) ;
321
+ ret. local_inits . push ( true ) ;
322
+ }
323
+ } else {
324
+ bail ! ( offset, "expected func type at index {ty}, found {sub_ty}" )
325
+ }
326
+
327
+ // If we're in a shared function, ensure we do not access unshared
328
+ // objects.
329
+ if sub_ty. composite_type . shared {
330
+ ret. shared = true ;
314
331
}
315
332
Ok ( ret)
316
333
}
@@ -912,14 +929,13 @@ where
912
929
/// Returns the corresponding function type for the `func` item located at
913
930
/// `function_index`.
914
931
fn type_of_function ( & self , function_index : u32 ) -> Result < & ' resources FuncType > {
915
- match self . resources . type_of_function ( function_index) {
916
- Some ( f) => Ok ( f) ,
917
- None => {
918
- bail ! (
919
- self . offset,
920
- "unknown function {function_index}: function index out of bounds" ,
921
- )
922
- }
932
+ if let Some ( type_index) = self . resources . type_index_of_function ( function_index) {
933
+ self . func_type_at ( type_index)
934
+ } else {
935
+ bail ! (
936
+ self . offset,
937
+ "unknown function {function_index}: function index out of bounds" ,
938
+ )
923
939
}
924
940
}
925
941
@@ -971,7 +987,7 @@ where
971
987
/// table.
972
988
///
973
989
/// The return value of this function is the function type behind
974
- /// `type_index` which must then be passedt o `check_{call,return_call}_ty`.
990
+ /// `type_index` which must then be passed to `check_{call,return_call}_ty`.
975
991
fn check_call_indirect_ty (
976
992
& mut self ,
977
993
type_index : u32 ,
@@ -1302,6 +1318,12 @@ where
1302
1318
fn struct_type_at ( & self , at : u32 ) -> Result < & ' resources StructType > {
1303
1319
let sub_ty = self . sub_type_at ( at) ?;
1304
1320
if let CompositeInnerType :: Struct ( struct_ty) = & sub_ty. composite_type . inner {
1321
+ if self . inner . shared && !sub_ty. composite_type . shared {
1322
+ bail ! (
1323
+ self . offset,
1324
+ "shared functions cannot access unshared structs" ,
1325
+ ) ;
1326
+ }
1305
1327
Ok ( struct_ty)
1306
1328
} else {
1307
1329
bail ! (
@@ -1342,6 +1364,12 @@ where
1342
1364
fn array_type_at ( & self , at : u32 ) -> Result < FieldType > {
1343
1365
let sub_ty = self . sub_type_at ( at) ?;
1344
1366
if let CompositeInnerType :: Array ( array_ty) = & sub_ty. composite_type . inner {
1367
+ if self . inner . shared && !sub_ty. composite_type . shared {
1368
+ bail ! (
1369
+ self . offset,
1370
+ "shared functions cannot access unshared arrays" ,
1371
+ ) ;
1372
+ }
1345
1373
Ok ( array_ty. 0 )
1346
1374
} else {
1347
1375
bail ! (
@@ -1365,6 +1393,12 @@ where
1365
1393
fn func_type_at ( & self , at : u32 ) -> Result < & ' resources FuncType > {
1366
1394
let sub_ty = self . sub_type_at ( at) ?;
1367
1395
if let CompositeInnerType :: Func ( func_ty) = & sub_ty. composite_type . inner {
1396
+ if self . inner . shared && !sub_ty. composite_type . shared {
1397
+ bail ! (
1398
+ self . offset,
1399
+ "shared functions cannot access unshared functions" ,
1400
+ ) ;
1401
+ }
1368
1402
Ok ( func_ty)
1369
1403
} else {
1370
1404
bail ! (
@@ -1382,6 +1416,12 @@ where
1382
1416
1383
1417
fn global_type_at ( & self , at : u32 ) -> Result < GlobalType > {
1384
1418
if let Some ( ty) = self . resources . global_at ( at) {
1419
+ if self . inner . shared && !ty. shared {
1420
+ bail ! (
1421
+ self . offset,
1422
+ "shared functions cannot access unshared globals" ,
1423
+ ) ;
1424
+ }
1385
1425
Ok ( ty)
1386
1426
} else {
1387
1427
bail ! ( self . offset, "unknown global: global index out of bounds" ) ;
@@ -1391,7 +1431,15 @@ where
1391
1431
/// Validates that the `table` is valid and returns the type it points to.
1392
1432
fn table_type_at ( & self , table : u32 ) -> Result < TableType > {
1393
1433
match self . resources . table_at ( table) {
1394
- Some ( ty) => Ok ( ty) ,
1434
+ Some ( ty) => {
1435
+ if self . inner . shared && !ty. shared {
1436
+ bail ! (
1437
+ self . offset,
1438
+ "shared functions cannot access unshared tables" ,
1439
+ ) ;
1440
+ }
1441
+ Ok ( ty)
1442
+ }
1395
1443
None => bail ! (
1396
1444
self . offset,
1397
1445
"unknown table {table}: table index out of bounds"
0 commit comments