[pypy-commit] lang-smalltalk default: (tfel, lwassermann):
lwassermann
noreply at buildbot.pypy.org
Tue Jun 18 16:04:13 CEST 2013
Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch:
Changeset: r454:40875946b055
Date: 2013-06-14 16:54 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/40875946b055/
Log: (tfel, lwassermann): added dynamic loading capabilities fixed
problem with execution folder identification (adapted from topaz)
fixed bool-function return values removed external bitblt hard link
to now actually call external function 'copyBits'
diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -94,8 +94,8 @@
raise NotImplementedError(
"InterpreterProxy: unknown result_type %s" % (result_type, ))
wrapped.func_name = "wrapped_ipf_" + func.func_name
- functions.append(("c_" + func.func_name, f_ptr, wrapped))
- return func
+ functions.append((func.func_name, f_ptr, wrapped))
+ return wrapped
return decorator
@expose_on_virtual_machine_proxy([], int)
@@ -1005,8 +1005,7 @@
# ##############################################################################
VirtualMachine = lltype.Struct("VirtualMachine",
- *map(lambda x: (x[0], x[1]), functions),
- hints={'c_name': 'VirtualMachine'})
+ *map(lambda x: (x[0], x[1]), functions))
VMPtr = Ptr(VirtualMachine)
proxy_functions = unrolling_iterable(functions)
@@ -1023,6 +1022,10 @@
# rffi.llexternal is supposed to represent c-functions.
+func_str_void = Ptr(FuncType([], sqStr))
+func_bool_vm = Ptr(FuncType([VMPtr], sqInt))
+func_bool_void = Ptr(FuncType([], sqInt))
+
class _InterpreterProxy(object):
_immutable_fields_ = ['vm_initialized?']
@@ -1032,6 +1035,7 @@
self._next_oop = 0
self.oop_map = {}
self.object_map = {}
+ self.loaded_modules = {}
self.remappable_objects = []
self.reset()
@@ -1043,6 +1047,30 @@
self.fail_reason = 0
def call(self, signature, interp, s_frame, argcount, s_method):
+ from rpython.rlib.rdynload import dlsym
+ self.initialize_from_call(signature, interp, s_frame, argcount, s_method)
+ try:
+ if signature[0] not in self.loaded_modules:
+ module = self.load_and_initialize(signature[0])
+ print "Successfully loaded: %s" % signature[0]
+ else:
+ module = self.loaded_modules[signature[0]]
+
+ # call the correct function in it...
+ try:
+ _external_function = dlsym(module, signature[1])
+ except KeyError:
+ self.failed()
+ else:
+ external_function = rffi.cast(func_bool_void, _external_function)
+ external_function()
+
+ if not self.fail_reason == 0:
+ raise error.PrimitiveFailedError
+ finally:
+ self.reset()
+
+ def initialize_from_call(self, signature, interp, s_frame, argcount, s_method):
self.interp = interp
self.s_frame = s_frame
self.argcount = argcount
@@ -1050,14 +1078,6 @@
self.space = interp.space
# ensure that space.w_nil gets the first possible oop
self.object_to_oop(self.space.w_nil)
- try:
- # Load the correct DLL
- self.failed()
- # call the correct function in it...
- if not self.fail_reason == 0:
- raise error.PrimitiveFailedError
- finally:
- self.reset()
def failed(self, reason=1):
assert reason != 0
@@ -1094,6 +1114,57 @@
self.remappable_objects.append(w_object)
return w_object
+ def top_remappable(self):
+ if len(self.remappable_objects) == 0:
+ raise ProxyFunctionFailed
+ return self.remappable_objects[-1]
+
+ def load_and_initialize(self, module_name):
+ from rpython.rlib.rdynload import dlopen, dlsym, dlclose, DLOpenError
+ import os
+ c_name = rffi.str2charp(os.path.join(IProxy.space.executable_path(), module_name))
+ try:
+ module = dlopen(c_name)
+ except DLOpenError, e:
+ print "Missing library: %s" % e
+ raise error.PrimitiveFailedError
+ try:
+ try:
+ _getModuleName = dlsym(module, "getModuleName")
+ except KeyError:
+ pass # the method does not need to exist
+ else:
+ getModuleName = rffi.cast(func_str_void, _getModuleName)
+ if not rffi.charp2str(getModuleName()).startswith(module_name):
+ raise error.PrimitiveFailedError
+
+ try:
+ _setInterpreter = dlsym(module, "setInterpreter")
+ except KeyError:
+ raise error.PrimitiveFailedError
+ else:
+ setInterpreter = rffi.cast(func_bool_vm, _setInterpreter)
+ if not setInterpreter(sqGetInterpreterProxy()):
+ print "Failed setting interpreter on: %s" % module_name
+ raise error.PrimitiveFailedError
+
+ try:
+ _initialiseModule = dlsym(module, "initialiseModule")
+ except KeyError:
+ pass # the method does not need to exist
+ else:
+ initialiseModule = rffi.cast(func_bool_void, _initialiseModule)
+ if not initialiseModule():
+ print "Failed initialization of: %s" % module_name
+ raise error.PrimitiveFailedError
+
+ self.loaded_modules[module_name] = module
+ return module
+ except error.PrimitiveFailedError:
+ dlclose(module)
+ raise
+
+
IProxy = _InterpreterProxy()
# # Class extensions for Array conversion
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -1,15 +1,40 @@
+import os
+
from spyvm import constants, model, shadow, wrapper
from spyvm.error import UnwrappingError, WrappingError, PrimitiveFailedError
-from rpython.rlib import jit
+from rpython.rlib import jit, rpath
from rpython.rlib.objectmodel import instantiate, specialize
from rpython.rlib.rarithmetic import intmask, r_uint, int_between
class ObjSpace(object):
def __init__(self):
self.classtable = {}
+ self._executable_path = [""] # XXX: we cannot set the attribute
+ # directly on the frozen objectspace
self.make_bootstrap_classes()
self.make_bootstrap_objects()
+ def find_executable(self, executable):
+ if os.sep in executable or (os.name == "nt" and ":" in executable):
+ return executable
+ path = os.environ.get("PATH")
+ if path:
+ for dir in path.split(os.pathsep):
+ f = os.path.join(dir, executable)
+ if os.path.isfile(f):
+ executable = f
+ break
+ return rpath.rabspath(executable)
+
+ def runtime_setup(self, executable):
+ fullpath = rpath.rabspath(self.find_executable(executable))
+ i = fullpath.rfind(os.path.sep) + 1
+ assert i > 0
+ self._executable_path[0] = fullpath[:i]
+
+ def executable_path(self):
+ return self._executable_path[0]
+
def make_bootstrap_classes(self):
def define_core_cls(name, w_superclass, w_metaclass):
assert name.startswith('w_')
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -839,9 +839,9 @@
raise PrimitiveFailedError
signature = (w_modulename.as_string(), w_functionname.as_string())
- if signature == ('BitBltPlugin', 'primitiveCopyBits'):
- return prim_holder.prim_table[BITBLT_COPY_BITS](interp, s_frame, argcount, s_method)
- elif signature[0] == "SocketPlugin":
+ # if signature == ('BitBltPlugin', 'primitiveCopyBits'):
+ # return prim_holder.prim_table[BITBLT_COPY_BITS](interp, s_frame, argcount, s_method)
+ if signature[0] == "SocketPlugin":
from spyvm.plugins.socket import SocketPlugin
return SocketPlugin.call(signature[1], interp, s_frame, argcount, s_method)
elif signature[0] == "FilePlugin":
@@ -994,7 +994,7 @@
@expose_primitive(VM_PATH, unwrap_spec=[object])
def func(interp, s_frame, w_receiver):
- return interp.space.wrap_string(os.path.join(os.getcwd(), ''))
+ return interp.space.wrap_string("%s%s" % (interp.space.executable_path(), os.path.sep))
@expose_primitive(SHORT_AT, unwrap_spec=[object, index1_0])
def func(interp, s_frame, w_receiver, n0):
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -136,6 +136,7 @@
image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata))
image = create_image(space, image_reader)
interp = interpreter.Interpreter(space, image, image_name=path, trace=trace)
+ space.runtime_setup(argv[0])
if benchmark is not None:
return _run_benchmark(interp, number, benchmark)
else:
More information about the pypy-commit
mailing list