On 07/06/2013 15:56, Gwenaël Casaccio wrote:
On 27/05/2013 17:15, Paolo Bonzini wrote:
Il 27/05/2013 12:26, Gwenaël Casaccio ha scritto:
On 27/05/2013 11:02, Paolo Bonzini wrote:
Il 27/05/2013 10:47, Gwenaël Casaccio ha scritto:
Hi,
Right now the only way to get the temps, args names from
methods and blocks is the use the source code and extract
those informations from it.
With the proposed patch I've added for each compiled method/block
a debug information with the args and the names, the class could be
extended to add line number inside it.
You can use a single array with arguments and temporaries
concatenated.
Otherwise the patch looks pretty good, thanks!
Paolo
Here is a new version with one array
Oops, sorry for not noticing this before: this must go in the
MethodInfo, or you break loading old images. CompiledCode (and
subclasses) have their format set in stone.
Paolo
Here is the new patch, it does the same but informations are added in
MethodInfo.
I've changed the grow_identity_dic I think that could create a leak
(if the object is
allocated in old space)
Cheers,
Gwen
Sorry but the change for grow_identity_dic was not needed.
Gwen
>From be049f45ae1a66bbaf185ac0a8efed54828f4eb2 Mon Sep 17 00:00:00 2001
From: Gwenael Casaccio <[email protected]>
Date: Fri, 7 Jun 2013 17:14:04 +0200
Subject: [PATCH] Add support for DebugInformation
---
ChangeLog | 15 +++++++++
kernel/CompildMeth.st | 24 ++++++++++++++
kernel/CompiledBlk.st | 12 +++++++
kernel/DebugInformation.st | 70 +++++++++++++++++++++++++++++++++++++++
kernel/MethodInfo.st | 14 +++++++-
libgst/comp.c | 81 +++++++++++++++++++++++++++++++++++++++++++---
libgst/comp.h | 2 ++
libgst/dict.c | 18 ++++++++---
libgst/dict.h | 7 ++++
libgst/files.c | 2 ++
packages.xml | 1 +
tests/stcompiler.ok | 7 ++++
tests/stcompiler.st | 20 ++++++++++++
13 files changed, 264 insertions(+), 9 deletions(-)
create mode 100644 kernel/DebugInformation.st
diff --git a/ChangeLog b/ChangeLog
index 8bc8710..ea52c19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2013-06-07 Gwenael Casaccio <[email protected]>
+
+ * kernel/DebugInformation.st: Add DebugInformation.
+ * kernel/CompildMeth.st: Add DebugInformation support.
+ * kernel/CompiledBlk.st: Add DebugInformation support.
+ * kernel/MethodInfo.st: Add DebugInformation support.
+ * libgst/comp.c: Add arguments and temporaries name in DebugInformation.
+ * libgst/comp.h: Add a debugInfo state in the compiler.
+ * libgst/dict.c: Add _gst_identity_dictionary_new.
+ * libgst/dict.h: Add _gst_identity_dictionary_new.
+ * libgst/files.c: Bootstrap information for DebugInformation.
+ * packages.xml: Bootstrap information for DebugInformation.
+ * tests/stcompiler.ok: Tests for DebugInformations.
+ * tests/stcompiler.st: Tests for DebugInformations.
+
2013-05-18 Holger Hans Peter Freyther <[email protected]>
* gst-tool.c: Add --no-line-numbers to the gst-remote command.
diff --git a/kernel/CompildMeth.st b/kernel/CompildMeth.st
index 45fc3b9..5a9b056 100644
--- a/kernel/CompildMeth.st
+++ b/kernel/CompildMeth.st
@@ -756,5 +756,29 @@ instances.'>
self become: newMethod.
^nil
]
+
+ arguments [
+ <category: 'accessing'>
+
+ ^ self argumentsFor: self
+ ]
+
+ temporaries [
+ <category: 'accessing'>
+
+ ^ self temporariesFor: self
+ ]
+
+ argumentsFor: anObject [
+ <category: 'accessing'>
+
+ ^ self descriptor argumentsFor: anObject
+ ]
+
+ temporariesFor: anObject [
+ <category: 'accessing'>
+
+ ^ self descriptor temporariesFor: anObject
+ ]
]
diff --git a/kernel/CompiledBlk.st b/kernel/CompiledBlk.st
index 96a2b8d..d5ca707 100644
--- a/kernel/CompiledBlk.st
+++ b/kernel/CompiledBlk.st
@@ -280,5 +280,17 @@ CompiledCode subclass: CompiledBlock [
receiver: self method]].
self error: 'object cannot be dumped'
]
+
+ arguments [
+ <category: 'accessing'>
+
+ ^ self method argumentsFor: self
+ ]
+
+ temporaries [
+ <category: 'accessing'>
+
+ ^ self method temporariesFor: self
+ ]
]
diff --git a/kernel/DebugInformation.st b/kernel/DebugInformation.st
new file mode 100644
index 0000000..23a1635
--- /dev/null
+++ b/kernel/DebugInformation.st
@@ -0,0 +1,70 @@
+"======================================================================
+|
+| Object Method Definitions
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2013 Free Software Foundation, Inc.
+| Written by Gwenael Casaccio.
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library is distributed in the hope that it will be
+| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================"
+
+
+Object subclass: DebugInformation [
+
+ DebugInformation class >> variables: anArray [
+ <category: 'instance creation'>
+
+ ^ self new
+ variables: anArray;
+ yourself
+ ]
+
+ | variables |
+
+ variables: anArray [
+ <category: 'initialization'>
+
+ variables := anArray.
+ ]
+
+ variables [
+ <category: 'accessing'>
+
+ ^ variables
+ ]
+
+ arguments: anInteger [
+ <category: 'accessing'>
+
+ ^ variables copyFrom: 1 to: anInteger
+ ]
+
+ temporaries: anInteger [
+ <category: 'accessing'>
+
+ ^ variables copyFrom: anInteger + 1 to: variables size
+ ]
+]
+
+
diff --git a/kernel/MethodInfo.st b/kernel/MethodInfo.st
index c58ba79..47ef495 100644
--- a/kernel/MethodInfo.st
+++ b/kernel/MethodInfo.st
@@ -33,7 +33,7 @@
Object subclass: MethodInfo [
- | sourceCode category class selector |
+ | sourceCode category class selector debugInfo |
<shape: #pointer>
<category: 'Language-Implementation'>
@@ -140,5 +140,17 @@ code of the method.'>
<category: 'private'>
sourceCode := source
]
+
+ argumentsFor: anObject [
+ <category: 'accessing'>
+
+ ^ (debugInfo at: anObject) arguments: anObject numArgs
+ ]
+
+ temporariesFor: anObject [
+ <category: 'accessing'>
+
+ ^ (debugInfo at: anObject) temporaries: anObject numArgs
+ ]
]
diff --git a/libgst/comp.c b/libgst/comp.c
index 10330e1..b6ce106 100644
--- a/libgst/comp.c
+++ b/libgst/comp.c
@@ -534,6 +534,9 @@ _gst_execute_statements (OOP receiverOOP,
memset (&s, 0, sizeof (s));
_gst_compiler_state->undeclared_temporaries = undeclared;
+ _gst_compiler_state->debugInfo = _gst_identity_dictionary_new (_gst_identity_dictionary_class, 6);
+ INC_ADD_OOP (_gst_compiler_state->debugInfo);
+
if (setjmp (_gst_compiler_state->bad_method) == 0)
{
resultOOP = _gst_make_constant_oop (statements->v_list.value);
@@ -692,6 +695,10 @@ _gst_compile_method (tree_node method,
OOP methodOOP;
bc_vector bytecodes;
int stack_depth;
+ int i, argCount, tempCount;
+ OOP variablesOOP, debugInfo;
+ gst_object object;
+ tree_node args;
inc_ptr incPtr;
gst_compiled_method compiledMethod;
@@ -719,6 +726,9 @@ _gst_compile_method (tree_node method,
_gst_push_new_scope ();
selector = compute_selector (method->v_method.selectorExpr);
+ _gst_compiler_state->debugInfo = _gst_identity_dictionary_new (_gst_identity_dictionary_class, 6);
+ INC_ADD_OOP (_gst_compiler_state->debugInfo);
+
/* When we are reading from stdin, it's better to write line numbers where
1 is the first line *in the current doit*, because for now the prompt
does not include the line number. This might change in the future.
@@ -738,14 +748,14 @@ _gst_compile_method (tree_node method,
methodOOP = _gst_nil_oop;
if (setjmp (_gst_compiler_state->bad_method) == 0)
{
- if (_gst_declare_arguments (method->v_method.selectorExpr) == -1)
+ if ((argCount = _gst_declare_arguments (method->v_method.selectorExpr)) == -1)
{
_gst_errorf_at (method->location.first_line,
"duplicate argument name");
EXIT_COMPILATION ();
}
- if (_gst_declare_temporaries (method->v_method.temporaries) == -1)
+ if ((tempCount = _gst_declare_temporaries (method->v_method.temporaries)) == -1)
{
_gst_errorf_at (method->location.first_line,
"duplicate temporary variable name");
@@ -826,11 +836,48 @@ _gst_compile_method (tree_node method,
selector, method->v_method.currentCategory,
method->location.file_offset,
method->v_method.endPos);
+
+ if (methodOOP != _gst_nil_oop) {
+ INC_ADD_OOP (methodOOP);
+
+ object = new_instance_with (_gst_array_class, argCount + tempCount, &variablesOOP);
+ INC_ADD_OOP (variablesOOP);
+
+ args = method->v_method.selectorExpr;
+ i = 0;
+
+ if (args->nodeType == TREE_BINARY_EXPR)
+ {
+ object->data[0] = _gst_intern_string (args->v_expr.expression->v_list.name);
+ i = i + 1;
+ }
+ else
+ {
+ for (args = args->v_expr.expression; args != NULL; args = args->v_list.next)
+ {
+ object->data[i] = _gst_intern_string (args->v_list.value->v_list.name);
+ i = i + 1;
+ }
+ }
+
+ for (args = method->v_method.temporaries; args != NULL; args = args->v_list.next)
+ {
+ object->data[i] = _gst_intern_string (args->v_list.name);
+ i = i + 1;
+ }
+
+ new_instance (_gst_debug_information_class, &debugInfo);
+ INC_ADD_OOP (debugInfo);
+
+ inst_var_at_put (debugInfo, 1, variablesOOP);
+ _gst_identity_dictionary_at_put (_gst_compiler_state->debugInfo, methodOOP, debugInfo);
+ inst_var_at_put (inst_var_at (methodOOP, 3), 5, _gst_compiler_state->debugInfo);
+ }
+
}
if (methodOOP != _gst_nil_oop)
{
- INC_ADD_OOP (methodOOP);
compiledMethod = (gst_compiled_method) OOP_TO_OBJ (methodOOP);
compiledMethod->header.isOldSyntax = method->v_method.isOldSyntax;
@@ -1064,9 +1111,13 @@ compile_block (tree_node blockExpr)
bc_vector current_bytecodes, blockByteCodes;
int argCount, tempCount;
int stack_depth;
- OOP blockClosureOOP, blockOOP;
+ int i;
+ OOP blockClosureOOP, blockOOP, variablesOOP;
+ OOP debugInfo;
gst_compiled_block block;
+ gst_object object;
inc_ptr incPtr;
+ tree_node args;
current_bytecodes = _gst_save_bytecode_array ();
@@ -1102,6 +1153,27 @@ compile_block (tree_node blockExpr)
blockOOP = make_block (_gst_get_arg_count (), _gst_get_temp_count (),
blockByteCodes, stack_depth);
INC_ADD_OOP (blockOOP);
+
+ object = new_instance_with (_gst_array_class, argCount + tempCount, &variablesOOP);
+ INC_ADD_OOP (variablesOOP);
+
+ for (i = 0, args = blockExpr->v_block.arguments; args != NULL; args = args->v_list.next) {
+ object->data[i] = _gst_intern_string (args->v_list.name);
+ i = i + 1;
+ }
+
+ for (args = blockExpr->v_block.temporaries; args != NULL; args = args->v_list.next) {
+ object->data[i] = _gst_intern_string (args->v_list.name);
+ i = i + 1;
+ }
+
+ new_instance (_gst_debug_information_class, &debugInfo);
+ INC_ADD_OOP (debugInfo);
+
+ inst_var_at_put (debugInfo, 1, variablesOOP);
+
+ _gst_identity_dictionary_at_put (_gst_compiler_state->debugInfo, blockOOP, debugInfo);
+
_gst_pop_old_scope ();
/* emit standard byte sequence to invoke a block:
@@ -2739,6 +2811,7 @@ method_info_new (OOP class,
methodInfo->category = categoryOOP;
methodInfo->class = class;
methodInfo->selector = selector;
+ methodInfo->debugInfo = _gst_nil_oop;
while (attrs)
{
diff --git a/libgst/comp.h b/libgst/comp.h
index 91a1f9c..6da68e5 100644
--- a/libgst/comp.h
+++ b/libgst/comp.h
@@ -148,6 +148,7 @@ typedef struct gst_method_info
OOP category;
OOP class;
OOP selector;
+ OOP debugInfo;
OOP attributes[1];
}
*gst_method_info;
@@ -234,6 +235,7 @@ typedef struct compiler_state
OOP *literal_vec;
OOP *literal_vec_curr;
OOP *literal_vec_max;
+ OOP debugInfo;
jmp_buf bad_method;
} compiler_state;
diff --git a/libgst/dict.c b/libgst/dict.c
index f4324b7..2770d66 100644
--- a/libgst/dict.c
+++ b/libgst/dict.c
@@ -177,6 +177,7 @@ OOP _gst_weak_key_identity_dictionary_class = NULL;
OOP _gst_weak_value_identity_dictionary_class = NULL;
OOP _gst_write_stream_class = NULL;
OOP _gst_processor_oop = NULL;
+OOP _gst_debug_information_class = NULL;
/* Called when a dictionary becomes full, this routine replaces the
dictionary instance that DICTIONARYOOP is pointing to with a new,
@@ -742,12 +743,16 @@ static const class_definition class_info[] = {
"Memory", NULL, NULL, NULL },
{&_gst_method_info_class, &_gst_object_class,
- GST_ISP_POINTER, true, 4,
- "MethodInfo", "sourceCode category class selector", NULL, NULL },
+ GST_ISP_POINTER, true, 5,
+ "MethodInfo", "sourceCode category class selector debugInfo", NULL, NULL },
{&_gst_file_segment_class, &_gst_object_class,
GST_ISP_FIXED, true, 3,
- "FileSegment", "file startPos size", NULL, NULL }
+ "FileSegment", "file startPos size", NULL, NULL },
+
+ {&_gst_debug_information_class, &_gst_object_class,
+ GST_ISP_FIXED, true, 1,
+ "DebugInformation", "variables", NULL, NULL }
/* Classes not defined here (like Point/Rectangle/RunArray) are
defined after the kernel has been fully initialized. */
@@ -1625,7 +1630,6 @@ grow_identity_dictionary (OOP oldIdentityDictionaryOOP)
identityDictionary =
instantiate_with (OOP_CLASS (oldIdentityDictionaryOOP), numFields * 2,
&identityDictionaryOOP);
-
oldIdentityDictionary = OOP_TO_OBJ (oldIdentityDictionaryOOP);
oldIdentDict = (gst_identity_dictionary) oldIdentityDictionary;
identDict = (gst_identity_dictionary) identityDictionary;
@@ -1721,6 +1725,12 @@ identity_dictionary_find_key_or_nil (OOP identityDictionaryOOP,
}
OOP
+_gst_identity_dictionary_new (OOP classOOP, int size)
+{
+ return identity_dictionary_new (classOOP, size);
+}
+
+OOP
identity_dictionary_new (OOP classOOP, int size)
{
gst_identity_dictionary identityDictionary;
diff --git a/libgst/dict.h b/libgst/dict.h
index 93224c9..84ca6b8 100644
--- a/libgst/dict.h
+++ b/libgst/dict.h
@@ -447,6 +447,7 @@ extern OOP _gst_weak_key_identity_dictionary_class ATTRIBUTE_HIDDEN;
extern OOP _gst_weak_value_identity_dictionary_class ATTRIBUTE_HIDDEN;
extern OOP _gst_write_stream_class ATTRIBUTE_HIDDEN;
extern OOP _gst_processor_oop ATTRIBUTE_HIDDEN;
+extern OOP _gst_debug_information_class ATTRIBUTE_HIDDEN;
/* The size of the indexed instance variables corresponding to the
various instanceSpec values declared in gstpriv.h. */
@@ -495,6 +496,12 @@ extern OOP _gst_dictionary_add (OOP dictionaryOOP,
OOP associationOOP)
ATTRIBUTE_HIDDEN;
+/* Create a new instance of CLASSOOP (an IdentityDictionary subclass)
+ and answer it. */
+extern OOP _gst_identity_dictionary_new (OOP classOOP,
+ int size)
+ ATTRIBUTE_HIDDEN;
+
/* Look for the value associated to KEYOOP in IDENTITYDICTIONARYOOP
and answer it or, if not found, _gst_nil_oop. */
extern OOP _gst_identity_dictionary_at (OOP identityDictionaryOOP,
diff --git a/libgst/files.c b/libgst/files.c
index a7156f9..913ade1 100644
--- a/libgst/files.c
+++ b/libgst/files.c
@@ -290,6 +290,8 @@ static const char standard_files[] = {
"PkgLoader.st\0"
"DirPackage.st\0"
"Autoload.st\0"
+
+ "DebugInformation.st\0"
};
/* The argc and argv that are passed to libgst via gst_smalltalk_args.
diff --git a/packages.xml b/packages.xml
index fc6a049..c3b6514 100644
--- a/packages.xml
+++ b/packages.xml
@@ -189,6 +189,7 @@
<file>LinkedList.st</file>
<file>Rectangle.st</file>
<file>AnsiDates.st</file>
+ <file>DebugInformation.st</file>
<file>CompildCode.st</file>
<file>LookupKey.st</file>
<file>BindingDict.st</file>
diff --git a/tests/stcompiler.ok b/tests/stcompiler.ok
index a0cebf4..4587736 100644
--- a/tests/stcompiler.ok
+++ b/tests/stcompiler.ok
@@ -60,3 +60,10 @@ Execution begins...
true
true
returned value is true
+
+Execution begins...
+true
+true
+true
+true
+returned value is nil
diff --git a/tests/stcompiler.st b/tests/stcompiler.st
index 5605a6e..a645741 100644
--- a/tests/stcompiler.st
+++ b/tests/stcompiler.st
@@ -140,3 +140,23 @@ Eval [
(bla sharedPools = #('STInST') asOrderedCollection) printNl.
(bla classVarNames = #('ClassInst') asOrderedCollection) printNl.
]
+
+"Test debug informations are generated"
+Object subclass: Foo [
+ a_1: i_1 a_2: i_2 [
+ | i j k |
+
+ ^ [ :a :b :c | | d e f | ]
+ ]
+]
+
+Eval [
+ | mth |
+ mth := Foo>>#'a_1:a_2:'.
+ (mth arguments = #(#'i_1' #'i_2')) printNl.
+ (mth temporaries = #(#'i' #'j' #'k')) printNl.
+ ((mth blockAt: 1) arguments = #(#'a' #'b' #'c')) printNl.
+ ((mth blockAt: 1) temporaries = #(#'d' #'e' #'f')) printNl.
+ nil
+]
+
--
1.8.1.2
_______________________________________________
help-smalltalk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-smalltalk