Loader.hx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) 2005, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. */
  25. package neko.vm;
  26. /**
  27. The Neko object that implements the loader.
  28. **/
  29. enum LoaderHandle {
  30. }
  31. /**
  32. Loaders can be used to dynamicly load Neko primitives stored in NDLL libraries.
  33. Loaders can be used to dynamicly load other Neko modules (.n bytecode files).
  34. Modules are referenced by names. To lookup the corresponding bytecode file, the
  35. default loader first look in its cache, then eventually adds the .n extension
  36. to the name and lookup the bytecode in its path.
  37. Loaders can be used for sandbox security. When a Module is loaded with a given
  38. Loader, this loader can manager the module security by filtering which
  39. primitives can be loaded by this module or by rewrapping them at loading-time
  40. with custom securized versions. Loaders are inherited in loaded submodules.
  41. **/
  42. class Loader {
  43. /**
  44. The abstract handle.
  45. **/
  46. public var l : LoaderHandle;
  47. public function new( l ) {
  48. this.l = l;
  49. }
  50. /**
  51. The default loader contains a search path in its [path] field. It's a
  52. linked list of Neko strings that is a parsed version of the [NEKOPATH].
  53. This path is used to lookup for modules and libraries.
  54. **/
  55. public function getPath() {
  56. var p = untyped l.path;
  57. var path = new Array<String>();
  58. while( p != null ) {
  59. path.push(new String(p[0]));
  60. p = cast p[1];
  61. }
  62. return path;
  63. }
  64. /**
  65. Adds a directory to the search path. See [getPath]
  66. **/
  67. public function addPath( s : String ) {
  68. untyped l.path = __dollar__array(s.__s,l.path);
  69. }
  70. /**
  71. The default loader contains a cache of already loaded modules. It's
  72. ensuring that the same module does not get loaded twice when circular
  73. references are occuring. The same module can eventually be loaded twice
  74. but with different names, for example with two relatives paths reprensenting
  75. the same file, since the cache is done on a by-name basic.
  76. **/
  77. public function getCache() : Hash<Module> {
  78. var h = new Hash<Module>();
  79. var cache = untyped l.cache;
  80. for( f in Reflect.fields(cache) )
  81. h.set(f,new Module(Reflect.field(cache,f)));
  82. return h;
  83. }
  84. /**
  85. Set a module in the loader cache.
  86. **/
  87. public function setCache( name : String, m : Module ) {
  88. Reflect.setField(untyped l.cache,name,m.m);
  89. }
  90. /**
  91. Change the cache value and returns the old value. This can be used
  92. to backup the loader cache and restore it later.
  93. **/
  94. public function backupCache( c : Dynamic ) : Dynamic {
  95. var old = untyped l.cache;
  96. untyped l.cache = c;
  97. return old;
  98. }
  99. function __compare( other : Loader ) {
  100. return untyped __dollar__compare(this.l,other.l);
  101. }
  102. /**
  103. Loads a neko primitive. By default, the name is of the form [library@method].
  104. The primitive might not be used directly in haXe since some of the Neko values
  105. needs an object wrapper in haXe.
  106. **/
  107. public function loadPrimitive( prim : String, nargs : Int ) : Dynamic {
  108. return untyped l.loadprim(prim.__s,nargs);
  109. }
  110. /**
  111. Loads a Module with the given name. If [loader] is defined, this will be
  112. this Module loader, else this loader will be inherited. When loaded this
  113. way, the module is directly executed.
  114. **/
  115. public function loadModule( modName : String, ?loader : Loader ) : Module {
  116. var exp = untyped l.loadmodule(modName.__s,if( loader == null ) l else loader.l);
  117. return new Module(exp.__module);
  118. }
  119. /**
  120. Returns the local Loader. This is the loader that was used to load the
  121. module in which the code is defined.
  122. **/
  123. public static function local() {
  124. return new Loader(untyped __dollar__loader);
  125. }
  126. /**
  127. Creates a loader using two methods. This loader will not have an accessible cache or path,
  128. although you can implement such mecanism in the methods body.
  129. **/
  130. public static function make( loadPrim : String -> Int -> Dynamic, loadModule : String -> Loader -> Module ) {
  131. var l = {
  132. loadprim : function(prim,nargs) {
  133. return loadPrim(new String(prim),nargs);
  134. },
  135. loadmodule : function(mname,loader) {
  136. return loadModule(new String(mname),new Loader(loader)).exportsTable();
  137. },
  138. args : untyped __dollar__amake(0),
  139. cache : {},
  140. };
  141. return new Loader(cast l);
  142. }
  143. }