1. my class Stash { # declared in BOOTSTRAP
  2. # class Stash is Hash
  3. # has str $!longname;
  4. multi method AT-KEY(Stash:D: Str() $key, :$global_fallback) is raw {
  5. my Mu $storage := nqp::defined(nqp::getattr(self, Map, '$!storage')) ??
  6. nqp::getattr(self, Map, '$!storage') !!
  7. nqp::bindattr(self, Map, '$!storage', nqp::hash());
  8. if nqp::existskey($storage, nqp::unbox_s($key)) {
  9. nqp::atkey($storage, nqp::unbox_s($key))
  10. }
  11. elsif $global_fallback {
  12. nqp::existskey(GLOBAL.WHO, $key)
  13. ?? GLOBAL.WHO.AT-KEY($key)
  14. !! fail("Could not find symbol '$key'")
  15. }
  16. else {
  17. nqp::p6bindattrinvres(my $v, Scalar, '$!whence',
  18. -> { nqp::bindkey($storage, nqp::unbox_s($key), $v) } )
  19. }
  20. }
  21. method package_at_key(Stash:D: str $key) {
  22. my Mu $storage := nqp::defined(nqp::getattr(self, Map, '$!storage')) ??
  23. nqp::getattr(self, Map, '$!storage') !!
  24. nqp::bindattr(self, Map, '$!storage', nqp::hash());
  25. if nqp::existskey($storage, nqp::unbox_s($key)) {
  26. nqp::atkey($storage, $key)
  27. }
  28. else {
  29. my $pkg := Metamodel::PackageHOW.new_type(:name($key));
  30. $pkg.^compose;
  31. nqp::bindkey($storage, $key, $pkg)
  32. }
  33. }
  34. multi method gist(Stash:D:) {
  35. self.Str
  36. }
  37. multi method Str(Stash:D:) {
  38. nqp::isnull_s($!longname) ?? '<anon>' !! $!longname
  39. }
  40. method merge-symbols(Stash:D: Hash $globalish) { # NQP gives a Hash, not a Stash
  41. nqp::gethllsym('perl6','ModuleLoader').merge_globals(self,$globalish)
  42. unless $globalish === Stash;
  43. }
  44. }