Mercurial > urweb
comparison src/iflow.sml @ 1245:5c2555dfce8f
Take advantage of equalities between get_cookie calls
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 18 Apr 2010 13:56:47 -0400 |
parents | 1eedc9086e6c |
children | fd4028a594a9 |
comparison
equal
deleted
inserted
replaced
1244:1eedc9086e6c | 1245:5c2555dfce8f |
---|---|
270 | 270 |
271 datatype node = Node of {Id : int, | 271 datatype node = Node of {Id : int, |
272 Rep : node ref option ref, | 272 Rep : node ref option ref, |
273 Cons : node ref SM.map ref, | 273 Cons : node ref SM.map ref, |
274 Variety : variety, | 274 Variety : variety, |
275 Known : bool ref} | 275 Known : bool ref, |
276 Ge : Int64.int option ref} | |
276 | 277 |
277 and variety = | 278 and variety = |
278 Dt0 of string | 279 Dt0 of string |
279 | Dt1 of string * node ref | 280 | Dt1 of string * node ref |
280 | Prim of Prim.t | 281 | Prim of Prim.t |
332 string "}", | 333 string "}", |
333 if b then | 334 if b then |
334 box [space, | 335 box [space, |
335 string "(complete)"] | 336 string "(complete)"] |
336 else | 337 else |
337 box []]] | 338 box []], |
339 if !(#Known (unNode n)) then | |
340 string " (known)" | |
341 else | |
342 box [], | |
343 case !(#Ge (unNode n)) of | |
344 NONE => box [] | |
345 | SOME n => string (" (>= " ^ Int64.toString n ^ ")")] | |
338 | 346 |
339 fun p_database (db : database) = | 347 fun p_database (db : database) = |
340 box [string "Vars:", | 348 box [string "Vars:", |
341 newline, | 349 newline, |
342 p_list_sep newline (fn (i, n) => box [string ("x" ^ Int.toString i), | 350 p_list_sep newline (fn (i, n) => box [string ("x" ^ Int.toString i), |
343 space, | 351 space, |
344 string "=", | 352 string "=", |
345 space, | 353 space, |
346 p_rep n, | 354 p_rep n]) (IM.listItemsi (!(#Vars db)))] |
347 if !(#Known (unNode n)) then | |
348 box [space, | |
349 string "(known)"] | |
350 else | |
351 box []]) (IM.listItemsi (!(#Vars db)))] | |
352 | 355 |
353 fun repOf (n : representative) : representative = | 356 fun repOf (n : representative) : representative = |
354 case !(#Rep (unNode n)) of | 357 case !(#Rep (unNode n)) of |
355 NONE => n | 358 NONE => n |
356 | SOME r => | 359 | SOME r => |
387 let | 390 let |
388 val r = ref (Node {Id = nodeId (), | 391 val r = ref (Node {Id = nodeId (), |
389 Rep = ref NONE, | 392 Rep = ref NONE, |
390 Cons = ref SM.empty, | 393 Cons = ref SM.empty, |
391 Variety = Prim p, | 394 Variety = Prim p, |
392 Known = ref true}) | 395 Known = ref true, |
396 Ge = ref (case p of | |
397 Prim.Int n => SOME n | |
398 | _ => NONE)}) | |
393 in | 399 in |
394 #Consts db := CM.insert (!(#Consts db), p, r); | 400 #Consts db := CM.insert (!(#Consts db), p, r); |
395 r | 401 r |
396 end) | 402 end) |
397 | Var n => (case IM.find (!(#Vars db), n) of | 403 | Var n => (case IM.find (!(#Vars db), n) of |
400 let | 406 let |
401 val r = ref (Node {Id = nodeId (), | 407 val r = ref (Node {Id = nodeId (), |
402 Rep = ref NONE, | 408 Rep = ref NONE, |
403 Cons = ref SM.empty, | 409 Cons = ref SM.empty, |
404 Variety = Nothing, | 410 Variety = Nothing, |
405 Known = ref false}) | 411 Known = ref false, |
412 Ge = ref NONE}) | |
406 in | 413 in |
407 #Vars db := IM.insert (!(#Vars db), n, r); | 414 #Vars db := IM.insert (!(#Vars db), n, r); |
408 r | 415 r |
409 end) | 416 end) |
410 | Lvar _ => raise Undetermined | 417 | Lvar _ => raise Undetermined |
414 let | 421 let |
415 val r = ref (Node {Id = nodeId (), | 422 val r = ref (Node {Id = nodeId (), |
416 Rep = ref NONE, | 423 Rep = ref NONE, |
417 Cons = ref SM.empty, | 424 Cons = ref SM.empty, |
418 Variety = Dt0 f, | 425 Variety = Dt0 f, |
419 Known = ref true}) | 426 Known = ref true, |
427 Ge = ref NONE}) | |
420 in | 428 in |
421 #Con0s db := SM.insert (!(#Con0s db), f, r); | 429 #Con0s db := SM.insert (!(#Con0s db), f, r); |
422 r | 430 r |
423 end) | 431 end) |
424 | Func (DtCon0 _, _) => raise Fail "Iflow.rep: DtCon0" | 432 | Func (DtCon0 _, _) => raise Fail "Iflow.rep: DtCon0" |
432 let | 440 let |
433 val r' = ref (Node {Id = nodeId (), | 441 val r' = ref (Node {Id = nodeId (), |
434 Rep = ref NONE, | 442 Rep = ref NONE, |
435 Cons = ref SM.empty, | 443 Cons = ref SM.empty, |
436 Variety = Dt1 (f, r), | 444 Variety = Dt1 (f, r), |
437 Known = ref (!(#Known (unNode r)))}) | 445 Known = ref (!(#Known (unNode r))), |
446 Ge = ref NONE}) | |
438 in | 447 in |
439 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r'); | 448 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r'); |
440 r' | 449 r' |
441 end | 450 end |
442 end | 451 end |
455 val cons = ref SM.empty | 464 val cons = ref SM.empty |
456 val r' = ref (Node {Id = nodeId (), | 465 val r' = ref (Node {Id = nodeId (), |
457 Rep = ref NONE, | 466 Rep = ref NONE, |
458 Cons = cons, | 467 Cons = cons, |
459 Variety = Nothing, | 468 Variety = Nothing, |
460 Known = ref (!(#Known (unNode r)))}) | 469 Known = ref (!(#Known (unNode r))), |
470 Ge = ref NONE}) | |
461 | 471 |
462 val r'' = ref (Node {Id = nodeId (), | 472 val r'' = ref (Node {Id = nodeId (), |
463 Rep = ref NONE, | 473 Rep = ref NONE, |
464 Cons = #Cons (unNode r), | 474 Cons = #Cons (unNode r), |
465 Variety = Dt1 (f, r'), | 475 Variety = Dt1 (f, r'), |
466 Known = #Known (unNode r)}) | 476 Known = #Known (unNode r), |
477 Ge = ref NONE}) | |
467 in | 478 in |
468 cons := SM.insert (!cons, f, r''); | 479 cons := SM.insert (!cons, f, r''); |
469 #Rep (unNode r) := SOME r''; | 480 #Rep (unNode r) := SOME r''; |
470 r' | 481 r' |
471 end | 482 end |
481 let | 492 let |
482 val r = ref (Node {Id = nodeId (), | 493 val r = ref (Node {Id = nodeId (), |
483 Rep = ref NONE, | 494 Rep = ref NONE, |
484 Cons = ref SM.empty, | 495 Cons = ref SM.empty, |
485 Variety = Nothing, | 496 Variety = Nothing, |
486 Known = ref false}) | 497 Known = ref false, |
498 Ge = ref NONE}) | |
487 in | 499 in |
488 #Funcs db := ((f, rs), r) :: (!(#Funcs db)); | 500 #Funcs db := ((f, rs), r) :: (!(#Funcs db)); |
489 r | 501 r |
490 end | 502 end |
491 | SOME (_, r) => repOf r | 503 | SOME (_, r) => repOf r |
509 | 521 |
510 val r' = ref (Node {Id = nodeId (), | 522 val r' = ref (Node {Id = nodeId (), |
511 Rep = ref NONE, | 523 Rep = ref NONE, |
512 Cons = ref SM.empty, | 524 Cons = ref SM.empty, |
513 Variety = Recrd (ref xes, true), | 525 Variety = Recrd (ref xes, true), |
514 Known = ref false}) | 526 Known = ref false, |
527 Ge = ref NONE}) | |
515 in | 528 in |
516 #Records db := (xes, r') :: (!(#Records db)); | 529 #Records db := (xes, r') :: (!(#Records db)); |
517 r' | 530 r' |
518 end | 531 end |
519 end | 532 end |
528 | NONE => let | 541 | NONE => let |
529 val r = ref (Node {Id = nodeId (), | 542 val r = ref (Node {Id = nodeId (), |
530 Rep = ref NONE, | 543 Rep = ref NONE, |
531 Cons = ref SM.empty, | 544 Cons = ref SM.empty, |
532 Variety = Nothing, | 545 Variety = Nothing, |
533 Known = ref (!(#Known (unNode r)))}) | 546 Known = ref (!(#Known (unNode r))), |
547 Ge = ref NONE}) | |
534 in | 548 in |
535 xes := SM.insert (!xes, f, r); | 549 xes := SM.insert (!xes, f, r); |
536 r | 550 r |
537 end) | 551 end) |
538 | Nothing => | 552 | Nothing => |
539 let | 553 let |
540 val r' = ref (Node {Id = nodeId (), | 554 val r' = ref (Node {Id = nodeId (), |
541 Rep = ref NONE, | 555 Rep = ref NONE, |
542 Cons = ref SM.empty, | 556 Cons = ref SM.empty, |
543 Variety = Nothing, | 557 Variety = Nothing, |
544 Known = ref (!(#Known (unNode r)))}) | 558 Known = ref (!(#Known (unNode r))), |
559 Ge = ref NONE}) | |
545 | 560 |
546 val r'' = ref (Node {Id = nodeId (), | 561 val r'' = ref (Node {Id = nodeId (), |
547 Rep = ref NONE, | 562 Rep = ref NONE, |
548 Cons = #Cons (unNode r), | 563 Cons = #Cons (unNode r), |
549 Variety = Recrd (ref (SM.insert (SM.empty, f, r')), false), | 564 Variety = Recrd (ref (SM.insert (SM.empty, f, r')), false), |
550 Known = #Known (unNode r)}) | 565 Known = #Known (unNode r), |
566 Ge = ref NONE}) | |
551 in | 567 in |
552 #Rep (unNode r) := SOME r''; | 568 #Rep (unNode r) := SOME r''; |
553 r' | 569 r' |
554 end | 570 end |
555 | _ => raise Contradiction | 571 | _ => raise Contradiction |
607 if !(#Known (unNode r2)) then | 623 if !(#Known (unNode r2)) then |
608 markKnown r1 | 624 markKnown r1 |
609 else | 625 else |
610 (); | 626 (); |
611 #Cons (unNode r2) := SM.unionWith #1 (!(#Cons (unNode r2)), !(#Cons (unNode r1))); | 627 #Cons (unNode r2) := SM.unionWith #1 (!(#Cons (unNode r2)), !(#Cons (unNode r1))); |
628 | |
629 case !(#Ge (unNode r1)) of | |
630 NONE => () | |
631 | SOME n1 => | |
632 case !(#Ge (unNode r2)) of | |
633 NONE => #Ge (unNode r2) := SOME n1 | |
634 | SOME n2 => #Ge (unNode r2) := SOME (Int64.max (n1, n2)); | |
612 | 635 |
613 compactFuncs ()) | 636 compactFuncs ()) |
614 | 637 |
615 and compactFuncs () = | 638 and compactFuncs () = |
616 let | 639 let |
661 let | 684 let |
662 val r' = ref (Node {Id = nodeId (), | 685 val r' = ref (Node {Id = nodeId (), |
663 Rep = ref NONE, | 686 Rep = ref NONE, |
664 Cons = ref SM.empty, | 687 Cons = ref SM.empty, |
665 Variety = Dt0 f, | 688 Variety = Dt0 f, |
666 Known = ref false}) | 689 Known = ref false, |
690 Ge = ref NONE}) | |
667 in | 691 in |
668 #Rep (unNode r) := SOME r'; | 692 #Rep (unNode r) := SOME r'; |
669 #Con0s db := SM.insert (!(#Con0s db), f, r') | 693 #Con0s db := SM.insert (!(#Con0s db), f, r') |
670 end) | 694 end) |
671 | _ => raise Contradiction | 695 | _ => raise Contradiction |
683 let | 707 let |
684 val r'' = ref (Node {Id = nodeId (), | 708 val r'' = ref (Node {Id = nodeId (), |
685 Rep = ref NONE, | 709 Rep = ref NONE, |
686 Cons = ref SM.empty, | 710 Cons = ref SM.empty, |
687 Variety = Nothing, | 711 Variety = Nothing, |
688 Known = ref (!(#Known (unNode r)))}) | 712 Known = ref (!(#Known (unNode r))), |
713 Ge = ref NONE}) | |
689 | 714 |
690 val r' = ref (Node {Id = nodeId (), | 715 val r' = ref (Node {Id = nodeId (), |
691 Rep = ref NONE, | 716 Rep = ref NONE, |
692 Cons = ref SM.empty, | 717 Cons = ref SM.empty, |
693 Variety = Dt1 (f, r''), | 718 Variety = Dt1 (f, r''), |
694 Known = #Known (unNode r)}) | 719 Known = #Known (unNode r), |
720 Ge = ref NONE}) | |
695 in | 721 in |
696 #Rep (unNode r) := SOME r' | 722 #Rep (unNode r) := SOME r' |
697 end | 723 end |
698 | _ => raise Contradiction | 724 | _ => raise Contradiction |
699 end | 725 end |
700 | (Eq, [e1, e2]) => | 726 | (Eq, [e1, e2]) => |
701 markEq (representative (db, e1), representative (db, e2)) | 727 markEq (representative (db, e1), representative (db, e2)) |
728 | (Ge, [e1, e2]) => | |
729 let | |
730 val r1 = representative (db, e1) | |
731 val r2 = representative (db, e2) | |
732 in | |
733 case !(#Ge (unNode (repOf r2))) of | |
734 NONE => () | |
735 | SOME n2 => | |
736 case !(#Ge (unNode (repOf r1))) of | |
737 NONE => #Ge (unNode (repOf r1)) := SOME n2 | |
738 | SOME n1 => #Ge (unNode (repOf r1)) := SOME (Int64.max (n1, n2)) | |
739 end | |
702 | _ => () | 740 | _ => () |
703 end | 741 end |
704 | 742 |
705 fun check (db, a) = | 743 fun check (db, a) = |
706 case a of | 744 case a of |
737 val r1 = representative (db, e1) | 775 val r1 = representative (db, e1) |
738 val r2 = representative (db, e2) | 776 val r2 = representative (db, e2) |
739 in | 777 in |
740 repOf r1 = repOf r2 | 778 repOf r1 = repOf r2 |
741 end | 779 end |
780 | (Ge, [e1, e2]) => | |
781 let | |
782 val r1 = representative (db, e1) | |
783 val r2 = representative (db, e2) | |
784 in | |
785 case (!(#Ge (unNode (repOf r1))), #Variety (unNode (repOf r2))) of | |
786 (SOME n1, Prim (Prim.Int n2)) => Int64.>= (n1, n2) | |
787 | _ => false | |
788 end | |
742 | _ => false | 789 | _ => false |
743 | 790 |
744 fun builtFrom (db, {UseKnown = uk, Base = bs, Derived = d}) = | 791 fun builtFrom (db, {UseKnown = uk, Base = bs, Derived = d}) = |
745 let | 792 let |
746 val bs = map (fn b => representative (db, b)) bs | 793 val bs = map (fn b => representative (db, b)) bs |
929 | Computed of string | 976 | Computed of string |
930 | Binop of Rel * sqexp * sqexp | 977 | Binop of Rel * sqexp * sqexp |
931 | SqKnown of sqexp | 978 | SqKnown of sqexp |
932 | Inj of Mono.exp | 979 | Inj of Mono.exp |
933 | SqFunc of string * sqexp | 980 | SqFunc of string * sqexp |
934 | Count | 981 | Unmodeled |
935 | 982 |
936 fun cmp s r = wrap (const s) (fn () => Exps (fn (e1, e2) => Reln (r, [e1, e2]))) | 983 fun cmp s r = wrap (const s) (fn () => Exps (fn (e1, e2) => Reln (r, [e1, e2]))) |
937 | 984 |
938 val sqbrel = altL [cmp "=" Eq, | 985 val sqbrel = altL [cmp "=" Eq, |
939 cmp "<>" Ne, | 986 cmp "<>" Ne, |
1009 constK "MIN", | 1056 constK "MIN", |
1010 constK "MAX", | 1057 constK "MAX", |
1011 constK "SUM", | 1058 constK "SUM", |
1012 constK "AVG"] | 1059 constK "AVG"] |
1013 | 1060 |
1061 val unmodeled = altL [const "COUNT(*)", | |
1062 const "CURRENT_TIMESTAMP"] | |
1063 | |
1014 fun sqexp chs = | 1064 fun sqexp chs = |
1015 log "sqexp" | 1065 log "sqexp" |
1016 (altL [wrap prim SqConst, | 1066 (altL [wrap prim SqConst, |
1017 wrap (const "TRUE") (fn () => SqTrue), | 1067 wrap (const "TRUE") (fn () => SqTrue), |
1018 wrap (const "FALSE") (fn () => SqFalse), | 1068 wrap (const "FALSE") (fn () => SqFalse), |
1019 wrap field Field, | 1069 wrap field Field, |
1020 wrap uw_ident Computed, | 1070 wrap uw_ident Computed, |
1021 wrap known SqKnown, | 1071 wrap known SqKnown, |
1022 wrap func SqFunc, | 1072 wrap func SqFunc, |
1023 wrap (const "COUNT(*)") (fn () => Count), | 1073 wrap unmodeled (fn () => Unmodeled), |
1024 wrap sqlify Inj, | 1074 wrap sqlify Inj, |
1025 wrap (follow (const "COALESCE(") (follow sqexp (follow (const ",") | 1075 wrap (follow (const "COALESCE(") (follow sqexp (follow (const ",") |
1026 (follow (keep (fn ch => ch <> #")")) (const ")"))))) | 1076 (follow (keep (fn ch => ch <> #")")) (const ")"))))) |
1027 (fn ((), (e, _)) => e), | 1077 (fn ((), (e, _)) => e), |
1028 wrap (follow (ws (const "(")) | 1078 wrap (follow (ws (const "(")) |
1172 | 1222 |
1173 val allowUpdate : atom list -> unit | 1223 val allowUpdate : atom list -> unit |
1174 val update : ErrorMsg.span -> unit | 1224 val update : ErrorMsg.span -> unit |
1175 | 1225 |
1176 val havocReln : reln -> unit | 1226 val havocReln : reln -> unit |
1227 val havocCookie : string -> unit | |
1177 | 1228 |
1178 val debug : unit -> unit | 1229 val debug : unit -> unit |
1179 end = struct | 1230 end = struct |
1180 | 1231 |
1181 val hnames = ref 1 | 1232 val hnames = ref 1 |
1327 in | 1378 in |
1328 tryAll unifs hyps | 1379 tryAll unifs hyps |
1329 end | 1380 end |
1330 | (g as AReln (r, es)) :: goals => | 1381 | (g as AReln (r, es)) :: goals => |
1331 (complete (); | 1382 (complete (); |
1332 Cc.check (db, AReln (r, map (simplify unifs) es)) | 1383 (if Cc.check (db, AReln (r, map (simplify unifs) es)) then |
1384 true | |
1385 else | |
1386 ((*Print.preface ("Fail", p_atom (AReln (r, map (simplify unifs) es)));*) | |
1387 false)) | |
1333 andalso checkGoals goals unifs) | 1388 andalso checkGoals goals unifs) |
1334 | ACond _ :: _ => false | 1389 | ACond _ :: _ => false |
1335 in | 1390 in |
1336 checkGoals goals IM.empty | 1391 checkGoals goals IM.empty |
1337 end | 1392 end |
1353 else | 1408 else |
1354 let | 1409 let |
1355 val (_, hs, _) = !hyps | 1410 val (_, hs, _) = !hyps |
1356 in | 1411 in |
1357 ErrorMsg.errorAt loc "The information flow policy may be violated here."; | 1412 ErrorMsg.errorAt loc "The information flow policy may be violated here."; |
1358 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs), | 1413 Print.prefaces "Situation" [("User learns", p_exp e), |
1359 ("User learns", p_exp e)(*, | 1414 ("Hypotheses", Print.p_list p_atom hs)(*, |
1360 ("E-graph", Cc.p_database db)*)] | 1415 ("E-graph", Cc.p_database db)*)] |
1361 end | 1416 end |
1362 end | 1417 end |
1363 | 1418 |
1364 fun checkPaths () = | 1419 fun checkPaths () = |
1406 else | 1461 else |
1407 let | 1462 let |
1408 val (_, hs, _) = !hyps | 1463 val (_, hs, _) = !hyps |
1409 in | 1464 in |
1410 ErrorMsg.errorAt loc "The database update policy may be violated here."; | 1465 ErrorMsg.errorAt loc "The database update policy may be violated here."; |
1411 Print.preface ("Hypotheses", Print.p_list p_atom hs) | 1466 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs)(*, |
1467 ("E-graph", Cc.p_database db)*)] | |
1412 end | 1468 end |
1413 end | 1469 end |
1414 | 1470 |
1415 val insertable = ref ([] : atom list list) | 1471 val insertable = ref ([] : atom list list) |
1416 fun allowInsert v = insertable := v :: !insertable | 1472 fun allowInsert v = insertable := v :: !insertable |
1438 val n = !hnames | 1494 val n = !hnames |
1439 val (_, hs, _) = !hyps | 1495 val (_, hs, _) = !hyps |
1440 in | 1496 in |
1441 hnames := n + 1; | 1497 hnames := n + 1; |
1442 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs, ref false) | 1498 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs, ref false) |
1499 end | |
1500 | |
1501 fun havocCookie cname = | |
1502 let | |
1503 val cname = "cookie/" ^ cname | |
1504 val n = !hnames | |
1505 val (_, hs, _) = !hyps | |
1506 in | |
1507 hnames := n + 1; | |
1508 hyps := (n, List.filter (fn AReln (Eq, [_, Func (Other f, [])]) => f <> cname | _ => true) hs, ref false) | |
1443 end | 1509 end |
1444 | 1510 |
1445 fun debug () = | 1511 fun debug () = |
1446 let | 1512 let |
1447 val (_, hs, _) = !hyps | 1513 val (_, hs, _) = !hyps |
1515 | SqFunc (f, e) => | 1581 | SqFunc (f, e) => |
1516 (case expIn e of | 1582 (case expIn e of |
1517 inl e => inl (Func (Other f, [e])) | 1583 inl e => inl (Func (Other f, [e])) |
1518 | _ => default ()) | 1584 | _ => default ()) |
1519 | 1585 |
1520 | Count => default () | 1586 | Unmodeled => default () |
1521 end | 1587 end |
1522 in | 1588 in |
1523 expIn | 1589 expIn |
1524 end | 1590 end |
1525 | 1591 |
1608 (case deinj (#Env arg) e of | 1674 (case deinj (#Env arg) e of |
1609 NONE => (ErrorMsg.errorAt loc "Expression injected into SQL is too complicated"; | 1675 NONE => (ErrorMsg.errorAt loc "Expression injected into SQL is too complicated"; |
1610 []) | 1676 []) |
1611 | SOME e => [(true, e)]) | 1677 | SOME e => [(true, e)]) |
1612 | SqFunc (_, e) => usedFields e | 1678 | SqFunc (_, e) => usedFields e |
1613 | Count => [] | 1679 | Unmodeled => [] |
1614 | 1680 |
1615 fun doUsed () = case #Where r of | 1681 fun doUsed () = case #Where r of |
1616 NONE => () | 1682 NONE => () |
1617 | SOME e => | 1683 | SOME e => |
1618 app (#UsedExp arg) (usedFields e) | 1684 app (#UsedExp arg) (usedFields e) |
1749 fun doFfi (m, s, es) = | 1815 fun doFfi (m, s, es) = |
1750 if m = "Basis" andalso SS.member (writers, s) then | 1816 if m = "Basis" andalso SS.member (writers, s) then |
1751 let | 1817 let |
1752 fun doArgs es = | 1818 fun doArgs es = |
1753 case es of | 1819 case es of |
1754 [] => k (Recd []) | 1820 [] => |
1821 (if s = "set_cookie" then | |
1822 case es of | |
1823 [_, cname, _, _, _] => | |
1824 (case #1 cname of | |
1825 EPrim (Prim.String cname) => | |
1826 St.havocCookie cname | |
1827 | _ => ()) | |
1828 | _ => () | |
1829 else | |
1830 (); | |
1831 k (Recd [])) | |
1755 | e :: es => | 1832 | e :: es => |
1756 evalExp env e (fn e => (St.send true (e, loc); doArgs es)) | 1833 evalExp env e (fn e => (St.send true (e, loc); doArgs es)) |
1757 in | 1834 in |
1758 doArgs es | 1835 doArgs es |
1759 end | 1836 end |
1994 | ESetval _ => default () | 2071 | ESetval _ => default () |
1995 | 2072 |
1996 | EUnurlify ((EFfiApp ("Basis", "get_cookie", [(EPrim (Prim.String cname), _)]), _), _, _) => | 2073 | EUnurlify ((EFfiApp ("Basis", "get_cookie", [(EPrim (Prim.String cname), _)]), _), _, _) => |
1997 let | 2074 let |
1998 val e = Var (St.nextVar ()) | 2075 val e = Var (St.nextVar ()) |
2076 val e' = Func (Other ("cookie/" ^ cname), []) | |
1999 in | 2077 in |
2000 St.assert [AReln (Known, [e])]; | 2078 St.assert [AReln (Known, [e]), AReln (Eq, [e, e'])]; |
2001 k e | 2079 k e |
2002 end | 2080 end |
2003 | 2081 |
2004 | EUnurlify _ => default () | 2082 | EUnurlify _ => default () |
2005 | EJavaScript _ => default () | 2083 | EJavaScript _ => default () |