One reason BulletML is useful compared to a general-purpose language is that you could arbitrarily recombine BulletML ASTs to produce valid bullet patterns, which Kenta Cho did for rRootage[0]. I think another reason that people implement VMs for these languages is that the host language lacks coroutines, so it cannot express the wait() function, and they don't want to turn their bullet pattern code inside-out. Even if the host language has coroutines, they may not be serializable, so saving your game in the middle of a level may not be possible if you build on top of coroutines, whereas it is definitely possible if you control the interpreter state of your DSL.
[0]: https://www.asahi-net.or.jp/~cs8k-cyu/windows/rr_e.html
Even in JavaScript, you might not want the full power of eval() exposed and instead you want something with less power that can be parsed and sanitized.
Personally, that's what attracts the artist side of me to this, like it's the ultimate creative product. There seems to be a lot of blogging and tweeting recently around the subject has also created a bit of an itch.