diff --git a/modules/Kernel/VM/SmallInteger.st b/modules/Kernel/VM/SmallInteger.st index 93ba54d..af13fd4 100644 --- a/modules/Kernel/VM/SmallInteger.st +++ b/modules/Kernel/VM/SmallInteger.st @@ -8,16 +8,19 @@ Extension { #name : #SmallInteger } { #category : '*Primitives' } SmallInteger >> - aNumber [ + ^(aNumber - self) negated ] { #category : '*Primitives' } SmallInteger >> != aNumber [ + ^aNumber != self ] { #category : '*Primitives' } SmallInteger >> * aNumber [ + ^aNumber * self ] { #category : '*Primitives' } @@ -33,21 +36,25 @@ SmallInteger >> \\ aNumber [ { #category : '*Primitives' } SmallInteger >> + aNumber [ + ^aNumber + self ] { #category : '*Primitives' } SmallInteger >> = aNumber [ + ^aNumber = self ] { #category : '*Primitives' } SmallInteger >> > aNumber [ + ^aNumber < self ] { #category : '*Primitives' } SmallInteger >> >= aNumber [ + ^aNumber <= self ] { #category : '*Primitives' } diff --git a/runtime/cpp/Bootstrapper.h b/runtime/cpp/Bootstrapper.h index d3e6b42..e60fce6 100644 --- a/runtime/cpp/Bootstrapper.h +++ b/runtime/cpp/Bootstrapper.h @@ -172,6 +172,7 @@ class Bootstrapper { return binding->valueWithin_(_runtime->_evaluator->context()); } ASSERT(false); + std::terminate(); } }; diff --git a/runtime/cpp/Evaluator/Evaluator.cpp b/runtime/cpp/Evaluator/Evaluator.cpp index df8cd9b..bd1ae92 100644 --- a/runtime/cpp/Evaluator/Evaluator.cpp +++ b/runtime/cpp/Evaluator/Evaluator.cpp @@ -460,6 +460,14 @@ Object* Evaluator::boolObject(bool aBoolean){ return (Object*)this->_runtime->booleanFor_(aBoolean); } +Object* Evaluator::failPrimitive() +{ + // failing a primitive implies skipping the return just after the primop bytecode + // after that return comes the normal Smalltalk failure code of the method + this->_context->incRegPC(); + return this->_regR; +} + Object* Evaluator::primitiveAt() { auto receiver = this->_context->self(); @@ -778,15 +786,24 @@ Object* Evaluator::primitiveSMIBitXor() { } Object* Evaluator::primitiveSMIEqual() { - return boolObject(this->_context->self()->asSmallInteger()->asNative() == (this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + boolObject(this->_context->self()->asSmallInteger()->asNative() == (arg->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSMIGreaterEqualThan() { - return boolObject(this->_context->self()->asSmallInteger()->asNative() >= (this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + boolObject(this->_context->self()->asSmallInteger()->asNative() >= (arg->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSMIGreaterThan() { - return boolObject(this->_context->self()->asSmallInteger()->asNative() > (this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + boolObject(this->_context->self()->asSmallInteger()->asNative() > (arg->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSMIHighBit() { @@ -809,11 +826,17 @@ Object* Evaluator::primitiveSMIMinus() { } Object* Evaluator::primitiveSMINotEqual() { - return boolObject(this->_context->self()->asSmallInteger()->asNative() != (this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + boolObject(this->_context->self()->asSmallInteger()->asNative() != (arg->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSMIPlus() { - return newIntObject((this->_context->self()->asSmallInteger()->asNative() + this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + newIntObject((this->_context->self()->asSmallInteger()->asNative() + this->_context->firstArgument()->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSMISize() { @@ -825,7 +848,10 @@ Object* Evaluator::primitiveSMISize() { } Object* Evaluator::primitiveSMITimes() { - return newIntObject((this->_context->self()->asSmallInteger()->asNative() * this->_context->firstArgument()->asSmallInteger()->asNative())); + auto arg = this->_context->firstArgument(); + return arg->isSmallInteger() ? + newIntObject((this->_context->self()->asSmallInteger()->asNative() * arg->asSmallInteger()->asNative())) : + this->failPrimitive(); } Object* Evaluator::primitiveSetBehavior() { diff --git a/runtime/cpp/Evaluator/Evaluator.h b/runtime/cpp/Evaluator/Evaluator.h index 9bdd877..d3aa48b 100644 --- a/runtime/cpp/Evaluator/Evaluator.h +++ b/runtime/cpp/Evaluator/Evaluator.h @@ -180,6 +180,8 @@ class Evaluator : public SExpressionVisitor { Object* newIntObject(auto anInteger); Object* boolObject(bool aBoolean); + Object* failPrimitive(); + Object* primitiveAt(); Object* primitiveAtPut(); Object* primitiveBehavior(); diff --git a/runtime/cpp/Evaluator/SExpressionLinearizer.cpp b/runtime/cpp/Evaluator/SExpressionLinearizer.cpp index 3ce888b..a0c6351 100644 --- a/runtime/cpp/Evaluator/SExpressionLinearizer.cpp +++ b/runtime/cpp/Evaluator/SExpressionLinearizer.cpp @@ -547,7 +547,6 @@ void SExpressionLinearizer::visitMethod(SMethod *anSMethod, HeapObject *method) PrimitivePointer primitive = this->_primitives[name]; this->primitive_(primitive); this->returnOp(); - return; } this->_stackTop = _runtime->methodTempCount_(anSMethod->compiledCode()); auto statements = anSMethod->statements(); diff --git a/runtime/cpp/Evaluator/TreecodeDecoder.h b/runtime/cpp/Evaluator/TreecodeDecoder.h index e5b6d40..31c6ca1 100644 --- a/runtime/cpp/Evaluator/TreecodeDecoder.h +++ b/runtime/cpp/Evaluator/TreecodeDecoder.h @@ -192,7 +192,6 @@ class TreecodeDecoder { this->_stream >> dummy; auto pragma = new SPragma(this->nextSymbolOrNil()); node->pragma_(pragma); - return node; } node->compiledCode_(this->_method); node->statements_(this->nextExpressionArray()); diff --git a/runtime/pharo/Powerlang-Core/EggEvaluator.class.st b/runtime/pharo/Powerlang-Core/EggEvaluator.class.st index 4486fda..345af32 100644 --- a/runtime/pharo/Powerlang-Core/EggEvaluator.class.st +++ b/runtime/pharo/Powerlang-Core/EggEvaluator.class.st @@ -115,6 +115,12 @@ EggEvaluator >> evaluatePrimitiveHash: receiver [ ^ runtime newInteger: hash ] +{ #category : 'primitives' } +EggEvaluator >> failPrimitive [ + context incRegPC. + ^self regR +] + { #category : 'initialization' } EggEvaluator >> false [ ^ falseObj @@ -619,24 +625,30 @@ EggEvaluator >> primitiveSMIBitXor [ { #category : 'primitives' } EggEvaluator >> primitiveSMIEqual [ - ^ [ runtime - booleanFor: ( - context self value = - context firstArgument value) ] + ^ [ + | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime booleanFor: context self value = arg value ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } EggEvaluator >> primitiveSMIGreaterEqualThan [ - ^ [ runtime - booleanFor: - context self value - >= (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime booleanFor: context self value >= (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } EggEvaluator >> primitiveSMIGreaterThan [ - ^ [ runtime - booleanFor: context self value > (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime booleanFor: context self value > (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } @@ -662,26 +674,29 @@ EggEvaluator >> primitiveSMIIntQuot [ { #category : 'primitives' } EggEvaluator >> primitiveSMIMinus [ - ^ [ runtime - newInteger: - context self value - - (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime newInteger: context self value - (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } EggEvaluator >> primitiveSMINotEqual [ - ^ [ runtime - booleanFor: - context self value - != (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime booleanFor: context self value != (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } EggEvaluator >> primitiveSMIPlus [ - ^ [ runtime - newInteger: - context self value - + (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime newInteger: context self value + (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } @@ -691,10 +706,11 @@ EggEvaluator >> primitiveSMISize [ { #category : 'primitives' } EggEvaluator >> primitiveSMITimes [ - ^ [ runtime - newInteger: - context self value - * (runtime integerFrom: context firstArgument) ] + ^ [ | arg | + arg := context firstArgument. + arg isImmediate + ifTrue: [ runtime newInteger: context self value * (runtime integerFrom: arg) ] + ifFalse: [ self failPrimitive ] ] ] { #category : 'primitives' } @@ -742,6 +758,11 @@ EggEvaluator >> primitiveUnderSize [ ^ [ runtime newInteger: context self size ] ] +{ #category : 'initializing' } +EggEvaluator >> regR [ + ^self subclassResponsibility +] + { #category : 'initializing' } EggEvaluator >> runtime [ ^runtime diff --git a/runtime/pharo/Powerlang-Core/EggIterativeInterpreter.class.st b/runtime/pharo/Powerlang-Core/EggIterativeInterpreter.class.st index ff27ba1..6481d06 100644 --- a/runtime/pharo/Powerlang-Core/EggIterativeInterpreter.class.st +++ b/runtime/pharo/Powerlang-Core/EggIterativeInterpreter.class.st @@ -37,6 +37,12 @@ EggIterativeInterpreter >> prepareForBlock: sblock [ ^self subclassResponsibility ] +{ #category : 'accessing' } +EggIterativeInterpreter >> regR [ + + ^regR +] + { #category : 'accessing' } EggIterativeInterpreter >> regR: anObject [ regR := anObject diff --git a/runtime/pharo/Powerlang-Core/SExpressionLinearizer.class.st b/runtime/pharo/Powerlang-Core/SExpressionLinearizer.class.st index b788e41..6fe8f48 100644 --- a/runtime/pharo/Powerlang-Core/SExpressionLinearizer.class.st +++ b/runtime/pharo/Powerlang-Core/SExpressionLinearizer.class.st @@ -622,13 +622,13 @@ SExpressionLinearizer >> visitMessage: anSMessage [ { #category : 'initialization' } SExpressionLinearizer >> visitMethod: anSMethod [ - | primitive statements symbol descriptor handler | + | primitive statements symbol handler | self reset. primitive := anSMethod pragma. primitive ifNotNil: [ symbol := runtime localSymbolFrom: anSMethod primitive. handler := primitives at: symbol. - ^ self + self primitive: handler; return ]. stackTop := runtime methodTempCount: anSMethod compiledCode.