[pypy-commit] lang-smalltalk stmgc-c7: primitives: implement GET_ATTRIBUTE

mswart noreply at buildbot.pypy.org
Thu Jun 19 12:43:28 CEST 2014


Author: Malte Swart <malte.swart at student.hpi.uni-potsdam.de>
Branch: stmgc-c7
Changeset: r846:247710759f02
Date: 2014-06-19 12:43 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/247710759f02/

Log:	primitives: implement GET_ATTRIBUTE

	Implement GET_ATTRIBUTE primitive to let the VM access command line
	and smalltalk arguments.

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -132,7 +132,8 @@
 class Interpreter(object):
     _immutable_fields_ = ["space", "image", "image_name",
                           "max_stack_depth", "interrupt_counter_size",
-                          "startup_time", "evented"]
+                          "startup_time", "evented",
+                          "vm_args", "smalltalk_args"]
     _w_last_active_context = None
     cnt = 0
     _last_indent = ""
@@ -145,7 +146,7 @@
     )
 
     def __init__(self, space, image=None, image_name="", trace=False,
-                 evented=True,
+                 evented=True, vm_args=['unknown'], smalltalk_args=[],
                  max_stack_depth=constants.MAX_LOOP_DEPTH):
         import time
         self.space = space
@@ -160,6 +161,8 @@
         self._loop = False
         self.next_wakeup_tick = 0
         self.evented = evented
+        self.vm_args = vm_args
+        self.smalltalk_args = smalltalk_args
         try:
             self.interrupt_counter_size = int(os.environ["SPY_ICS"])
         except KeyError:
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -1101,6 +1101,7 @@
 SHORT_AT_PUT = 144
 FILL = 145
 CLONE = 148
+GET_ATTRIBUTE = 149
 
 @expose_primitive(BEEP, unwrap_spec=[object])
 def func(interp, s_frame, w_receiver):
@@ -1143,6 +1144,42 @@
 def func(interp, s_frame, w_arg):
     return w_arg.clone(interp.space)
 
+ at expose_primitive(GET_ATTRIBUTE, unwrap_spec=[object, int])
+def func(interp, s_frame, _, idx):
+    if idx < 0:  # VM argument
+        vm_arg = -idx
+        if vm_arg < len(interp.vm_args):
+            return interp.space.wrap_string(interp.vm_args[vm_arg])
+        else:
+            return interp.space.w_nil
+    elif idx == 0:
+        return interp.space.wrap_string(interp.vm_args[0])
+    elif idx == 1:
+        return interp.space.wrap_string(interp.image_name)
+    elif idx == 1001:
+        # OS type: "unix", "win32", "mac", ...
+        return interp.space.w_nil
+    elif idx == 1002:
+        # OS name: "solaris2.5" on unix, "win95" on win32, ...
+        return interp.space.w_nil
+    elif idx == 1003:
+        # processor architecture: "68k", "x86", "PowerPC", ...
+        return interp.space.w_nil
+    elif idx == 1004:
+        # Interpreter version string
+        return interp.space.w_nil
+    elif idx == 1005:
+        # window system name
+        return interp.space.w_nil
+    elif idx == 1006:
+        # vm build string
+        return interp.space.w_nil
+    else:
+        smalltalk_arg = idx - 2
+        if smalltalk_arg < len(interp.smalltalk_args):
+            return interp.space.wrap_string(interp.smalltalk_args[smalltalk_arg])
+        return interp.space.w_nil
+
 # ___________________________________________________________________________
 # File primitives (150-169)
 # (XXX they are obsolete in Squeak and done with a plugin)
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -37,7 +37,7 @@
 
 IMAGENAME = "anImage.image"
 
-def mock(stack, context = None):
+def mock(stack, context = None, interp=None):
     mapped_stack = [wrap(x) for x in stack]
     if context is None:
         frame = MockFrame(mapped_stack)
@@ -45,11 +45,12 @@
         frame = context
         for i in range(len(stack)):
             frame.as_context_get_shadow(space).push(stack[i])
-    interp = interpreter.Interpreter(space, image_name=IMAGENAME)
+    if interp is None:
+        interp = interpreter.Interpreter(space, image_name=IMAGENAME)
     return (interp, frame, len(stack))
 
-def prim(code, stack, context = None):
-    interp, w_frame, argument_count = mock(stack, context)
+def prim(code, stack, context = None, interp=None):
+    interp, w_frame, argument_count = mock(stack, context, interp=interp)
     prim_table[code](interp, w_frame.as_context_get_shadow(space), argument_count-1)
     res = w_frame.as_context_get_shadow(space).pop()
     s_frame = w_frame.as_context_get_shadow(space)
@@ -823,3 +824,39 @@
 #   primitives.VALUE_WITH_ARGS is tested in test_interpreter
 #   primitives.OBJECT_AT is tested in test_interpreter
 #   primitives.OBJECT_AT_PUT is tested in test_interpreter
+
+
+class TestPrimGetAttribute:
+    def get_argument(self, idx, **kwargs):
+        kwargs.setdefault('image_name', IMAGENAME)
+        interp = interpreter.Interpreter(space, **kwargs)
+        result = prim(primitives.GET_ATTRIBUTE, [idx], interp=interp)
+        if result.is_same_object(space.w_nil):
+            return None
+        else:
+            return result.as_string()
+
+    # VM args:
+    def test_not_passed_vm_argument(self):
+        assert self.get_argument(-1, vm_args=['rsqueask']) is None
+
+    def test_first_vm_argument(self):
+        assert self.get_argument(-1, vm_args=['rsqueask', 'test']) == 'test'
+
+    def test_second_vm_argument(self):
+        assert self.get_argument(-2, vm_args=['rsqueask', 'test', 'foo']) == 'foo'
+
+    # interp name:
+    def test_interp_name(self):
+        assert self.get_argument(0) == 'unknown'
+
+    # image name:
+    def test_image_name(self):
+        assert self.get_argument(1) == IMAGENAME
+
+    # smalltalk args:
+    def test_smalltalk_first_argument(self):
+        assert self.get_argument(2, smalltalk_args=['example.st']) == 'example.st'
+
+    def test_smalltalk_no_argument(self):
+        assert self.get_argument(2) is None
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -144,10 +144,13 @@
     stringarg = ""
     code = None
     as_benchmark = False
+    smalltalk_args = []
 
     while idx < len(argv):
         arg = argv[idx]
-        if arg in ["-h", "--help"]:
+        if path is not None: # smalltalk args
+            smalltalk_args.append(arg)
+        elif arg in ["-h", "--help"]:
             _usage(argv)
             return 0
         elif arg in ["-j", "--jit"]:
@@ -204,7 +207,10 @@
 
     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, evented=evented)
+    interp = interpreter.Interpreter(space, image, trace=trace, evented=evented,
+                                     image_name=path,
+                                     vm_args=argv, smalltalk_args=smalltalk_args,
+                                     )
     space.runtime_setup(argv[0])
     if benchmark is not None:
         return _run_benchmark(interp, number, benchmark, stringarg)


More information about the pypy-commit mailing list