Exemple #1
0
		llvm::Value*
		LivenessEmitter::emitIsLiveCall(const AST::Type* const type, llvm::Value* const value) {
			auto& module = irEmitter_.module();
			
			// Call __islive method.
			if (type->isObject()) {
				TypeInfo typeInfo(module);
				if (!typeInfo.objectHasLivenessIndicator(*(type->getObjectType()))) {
					// Assume value is always live.
					return ConstantGenerator(module).getBool(true);
				}
				
				// Call __islive method.
				const auto methodName = module.getCString("__islive");
				const auto functionType = type->getObjectType()->getFunction(methodName).type();
				
				MethodInfo methodInfo(type, methodName, functionType, {});
				const auto contextArg = RefPendingResult(value, type);
				
				CallEmitter callEmitter(irEmitter_);
				return callEmitter.emitDynamicMethodCall(methodInfo, contextArg, {});
			}
			
			llvm_unreachable("Unknown __islive value type.");
		}
		void createPrimitiveMethod(Module& module, const SEM::TypeInstance* const typeInstance, SEM::Function* const semFunction, llvm::Function& llvmFunction) {
			const auto argInfo = getFunctionArgInfo(module, semFunction->type());
			Function function(module, llvmFunction, argInfo, &(module.templateBuilder(TemplatedObject::TypeInstance(typeInstance))));
			
			const auto debugSubprogram = genDebugFunctionInfo(module, semFunction, &llvmFunction);
			assert(debugSubprogram);
			function.attachDebugInfo(*debugSubprogram);
			
			function.setDebugPosition(semFunction->debugInfo()->scopeLocation.range().start());
			
			SEM::ValueArray templateArgs;
			for (const auto& templateVar: semFunction->templateVariables()) {
				templateArgs.push_back(templateVar->selfRefValue());
			}
			
			PendingResultArray args;
			const auto contextValue =
				argInfo.hasContextArgument() ?
					function.getContextValue(typeInstance) :
					nullptr;
			RefPendingResult contextPendingResult(contextValue, typeInstance->selfType());
			if (argInfo.hasContextArgument()) {
				args.push_back(contextPendingResult);
			}
			
			// Need an array to store all the pending results
			// being referred to in 'genTrivialPrimitiveFunctionCall'.
			Array<ValuePendingResult, 10> pendingResultArgs;
			
			const auto& argTypes = semFunction->type().parameterTypes();
			for (size_t i = 0; i < argTypes.size(); i++) {
				const auto argValue = function.getArg(i);
				pendingResultArgs.push_back(ValuePendingResult(argValue, argTypes[i]));
				args.push_back(pendingResultArgs.back());
			}
			
			MethodInfo methodInfo(typeInstance->selfType(), semFunction->name().last(), semFunction->type(), std::move(templateArgs));
			
			const auto hintResultValue = argInfo.hasReturnVarArgument() ? function.getReturnVar() : nullptr;
			const auto result = genTrivialPrimitiveFunctionCall(function, std::move(methodInfo), std::move(args), hintResultValue);
			
			const auto returnType = semFunction->type().returnType();
			
			// Return the result in the appropriate way.
			if (argInfo.hasReturnVarArgument()) {
				genMoveStore(function, result, function.getReturnVar(), returnType);
				function.getBuilder().CreateRetVoid();
			} else if (!returnType->isBuiltInVoid()) {
				function.returnValue(result);
			} else {
				function.getBuilder().CreateRetVoid();
			}
			
			// Check the generated function is correct.
			function.verify();
		}
Exemple #3
0
/**
 * Função que le a segunda parte de informações gerais de um arquivo .class
 * 
 * @param referência ao classfile.
 * @param referência ao arquivo sendo lido.
 */
void secondGeneralInfo(classFile* cf, FILE* file){
	cf->access_flags = le2Bytes(file);
	cf->this_class = le2Bytes(file);
	cf->super_class = le2Bytes(file);

	cf->interfaces_count = le2Bytes(file);
	interfaceInfo(cf,file,cf->interfaces_count);

	cf->fields_count = le2Bytes(file);
	fieldInfo(cf,file,cf->fields_count);

	cf->methods_count = le2Bytes(file);
	methodInfo(cf,file,cf->methods_count);
	cf->attributes_count = le2Bytes(file);
	attributeInfo(cf,file,cf->attributes_count);
}
		llvm::Value* callRawCastMethod(Function& function, llvm::Value* const castFromValue, const SEM::Type* const castFromType,
				const String& targetMethodName, const SEM::Type* const castToType, llvm::Value* const hintResultValue) {
			const bool isVarArg = false;
			const bool isMethod = false;
			const bool isTemplated = false;
			auto noexceptPredicate = SEM::Predicate::True();
			const auto returnType = castToType;
			const SEM::TypeArray parameterTypes = castFromValue != nullptr ? SEM::TypeArray{ castFromType } : SEM::TypeArray{};
			
			SEM::FunctionAttributes functionAttributes(isVarArg, isMethod, isTemplated, std::move(noexceptPredicate));
			const SEM::FunctionType functionType(std::move(functionAttributes), returnType, parameterTypes.copy());
			
			MethodInfo methodInfo(castToType, targetMethodName, functionType, {});
			
			PendingResultArray args;
			const ValuePendingResult contextPendingResult(castFromValue, castFromType);
			if (castFromValue != nullptr) {
				args.push_back(contextPendingResult);
			}
			return genStaticMethodCall(function, std::move(methodInfo), std::move(args), hintResultValue);
		}
Exemple #5
0
		void
		LivenessEmitter::emitSetInvalidCall(const AST::Type* const type, llvm::Value* const value) {
			auto& module = irEmitter_.module();
			
			// Call __setinvalid method.
			if (type->isObject()) {
				const auto methodName = module.getCString("__setinvalid");
				const auto functionType = type->getObjectType()->getFunction(methodName).type();
				
				MethodInfo methodInfo(type, methodName, functionType, {});
				const auto contextArg = RefPendingResult(value, type);
				
				CallEmitter callEmitter(irEmitter_);
				callEmitter.emitDynamicMethodCall(methodInfo, contextArg, {});
				return;
			} else if (type->isTemplateVar()) {
				// TODO!
				return;
			}
			
			llvm_unreachable("Unknown __setinvalid value type.");
		}
void PythonQtSignalTarget::call(void **arguments) const {
  PyObject* result = call(_callable, methodInfo(), arguments);
  if (result) {
    Py_DECREF(result);
  }
}
void PythonQtSignalTarget::call(void **arguments) const
{
  // Note: we check if the callable is a PyFunctionObject and has a fixed number of arguments
  // if that is the case, we only pass these arguments to python and skip the additional arguments from the signal
  
  int numPythonArgs = -1;
  if (PyFunction_Check(_callable)) {
    PyObject* o = _callable;
    PyFunctionObject* func = (PyFunctionObject*)o;
    PyCodeObject* code = (PyCodeObject*)func->func_code;
    if (!(code->co_flags & 0x04)) {
      numPythonArgs = code->co_argcount;
    } else {
      // variable numbers of arguments allowed
    }
  } else if (PyMethod_Check(_callable)) {
    PyObject* o = _callable;
    PyMethodObject* method = (PyMethodObject*)o;
    if (PyFunction_Check(method->im_func)) {
      PyFunctionObject* func = (PyFunctionObject*)method->im_func;
      PyCodeObject* code = (PyCodeObject*)func->func_code;
      if (!(code->co_flags & 0x04)) {
        numPythonArgs = code->co_argcount - 1; // we subtract one because the first is "self"
      } else {
        // variable numbers of arguments allowed
      }
    }
  }

  const PythonQtMethodInfo* m = methodInfo();
  // parameterCount includes return value:
  int count = m->parameterCount();
  if (numPythonArgs!=-1) {
    if (count>numPythonArgs+1) {
      // take less arguments
      count = numPythonArgs+1;
    }
  }

  PyObject* pargs = NULL;
  if (count>1) {
    pargs = PyTuple_New(count-1);
  }
  bool err = false;
  // transform Qt values to Python
  const QList<PythonQtMethodInfo::ParameterInfo>& params = m->parameters();
  for (int i = 1; i < count; i++) {
    const PythonQtMethodInfo::ParameterInfo& param = params.at(i);
    PyObject* arg = PythonQtConv::ConvertQtValueToPython(param, arguments[i]);
    if (arg) {
      // steals reference, no unref
      PyTuple_SetItem(pargs, i-1,arg);
    } else {
      err = true;
      break;
    }
  }

  if (!err) {
    PyErr_Clear();
    PyObject* result = PyObject_CallObject(_callable, pargs);
    if (result) {
      // ok
      Py_DECREF(result);
    } else {
      PythonQt::self()->handleError();
    }
  }
  if (pargs) {
    // free the arguments again
    Py_DECREF(pargs);
  }
}