[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