js_export.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package ngjsvm
  2. import (
  3. "git.swzry.com/zry/GoHiedaLogger/hiedalog"
  4. "github.com/dop251/goja"
  5. "github.com/dop251/goja_nodejs/require"
  6. "sync"
  7. )
  8. type JSEnv struct {
  9. jsvm *JSVM
  10. logger *hiedalog.HiedaLogger
  11. logPrefix string
  12. rtRumtimes map[string]JsRtInterface
  13. mapLock sync.RWMutex
  14. registry *require.Registry
  15. requireModule *require.RequireModule
  16. }
  17. type JsRtInterface interface {
  18. RegisterRt(name string, env *JSEnv) (goja.Value, error)
  19. IsRegistered() bool
  20. Dispose()
  21. }
  22. func NewJSEnv(vm *JSVM, logger *hiedalog.HiedaLogger, logPrefix string) *JSEnv {
  23. je := &JSEnv{
  24. jsvm: vm,
  25. logger: logger,
  26. logPrefix: logPrefix,
  27. rtRumtimes: make(map[string]JsRtInterface),
  28. mapLock: sync.RWMutex{},
  29. }
  30. je.registry = require.NewRegistryWithLoader(je.registryLoader)
  31. je.prepareBasicJsEnv()
  32. return je
  33. }
  34. func (v *JSEnv) EnableRegistry(gojaVM *goja.Runtime) {
  35. v.requireModule = v.registry.Enable(gojaVM)
  36. }
  37. func (v *JSEnv) registryLoader(path string) ([]byte, error) {
  38. return v.jsvm.RegistryLoaderFunc(path)
  39. }
  40. func (v *JSEnv) AddRt(name string, newJSRt JsRtInterface) {
  41. if newJSRt == nil {
  42. v.logger.LogPrintf(v.logPrefix, hiedalog.DLN_WARN, "register a nil Rt '%s'", name)
  43. return
  44. }
  45. if newJSRt.IsRegistered() {
  46. v.logger.LogPrintf(v.logPrefix, hiedalog.DLN_VERBOSE, "register a Rt '%s' which is already registered. Ignored.", name)
  47. return
  48. }
  49. v.mapLock.Lock()
  50. defer v.mapLock.Unlock()
  51. _, exists := v.rtRumtimes[name]
  52. if exists {
  53. v.logger.LogPrintf(v.logPrefix, hiedalog.DLN_VERBOSE, "register a Rt '%s' that there is one already registered with this name. Ignored.", name)
  54. return
  55. }
  56. obj, err := newJSRt.RegisterRt(name, v)
  57. if err != nil {
  58. v.logger.LogPrintf(v.logPrefix, hiedalog.DLN_WARN, "register Rt '%s' failed: RegisterRt: %v", name, err)
  59. return
  60. }
  61. err = v.jsvm.RegisterObject(name, obj)
  62. if err != nil {
  63. newJSRt.Dispose()
  64. v.logger.LogPrintf(v.logPrefix, hiedalog.DLN_WARN, "register Rt '%s' failed: VM.RegisterObject: %v", name, err)
  65. return
  66. }
  67. v.rtRumtimes[name] = newJSRt
  68. }
  69. func (v *JSEnv) JSCallQuit() {
  70. v.jsvm.JSCallQuit()
  71. }
  72. func (v *JSEnv) EnvDispose() {
  73. v.mapLock.Lock()
  74. defer v.mapLock.Unlock()
  75. for k, val := range v.rtRumtimes {
  76. val.Dispose()
  77. delete(v.rtRumtimes, k)
  78. }
  79. }
  80. func (v *JSEnv) EmptyObject() *goja.Object {
  81. return v.jsvm.EmptyObject()
  82. }
  83. func (env *JSEnv) BuildObject(rootPath string, inmap map[string]interface{}) *goja.Object {
  84. root := env.EmptyObject()
  85. for k, v := range inmap {
  86. err := root.Set(k, v)
  87. if err != nil {
  88. env.logger.LogPrintf(env.logPrefix, hiedalog.DLN_WARN, "export object '%s.%s' failed: VM.RegisterObject: %v", rootPath, v, err)
  89. }
  90. }
  91. return root
  92. }
  93. func (v *JSEnv) lsrt(call goja.FunctionCall) goja.Value {
  94. v.mapLock.RLock()
  95. defer v.mapLock.RUnlock()
  96. l := make([]string, 0, len(v.rtRumtimes))
  97. for k, _ := range v.rtRumtimes {
  98. l = append(l, k)
  99. }
  100. ret := v.jsvm.VMToValue(l)
  101. return ret
  102. }
  103. func (v *JSEnv) GetCurrentScopeName() string {
  104. return v.jsvm.GetCurrentScopeName()
  105. }
  106. func (v *JSEnv) prepareBasicJsEnv() {
  107. _ = v.jsvm.RegisterObject("module", v.jsvm.GetGlobalObject())
  108. _ = v.jsvm.RegisterObject("lsrt", v.lsrt)
  109. }
  110. func (v *JSEnv) ThrowException(i interface{}) {
  111. v.jsvm.ThrowException(i)
  112. }
  113. func (v *JSEnv) ToValue(i interface{}) goja.Value {
  114. return v.jsvm.ToValue(i)
  115. }